diff --git a/README.md b/README.md index e140285..ffda07f 100644 --- a/README.md +++ b/README.md @@ -1,130 +1,130 @@ -## Project in self +# TypeScript API with authentication -API made with Typescript, MongoDB and JsonWebToken as main technologies. -This API has an **no-sesion** authentication, made by passport-jwt, for endpoints. Based on **MVC** architecture. +This project purpose is to learn about JWT auth flow, using TypeScript. -## To start +## Run Locally -### `npm install` +1. Install both: -To install all dependencies before run any other script. + - [Node.js](https://nodejs.org/es/download/) + - [MongoDB](https://www.mongodb.com/try/download/community) -### `npm run dev` + You will need to have MongoDB running on port 27017. -Script automatically compiles tsc and watch for changes. Only runs 1 time. +2. Clone the project: -### `npm run build` + ```bash + git clone https://github.com/AloisCRR/jwt-api-users-auth.git + ``` -Compiles tsc code (this is more for production) +3. Go to the project directory: -### `npm start` + ```bash + cd jwt-api-users-auth + ``` -Starts project after `npm run build` +4. Install dependencies: -After that, you can open the project in... -``` javascript -http://localhost:3000 -``` -Or you can define a port in eviroment variables... -``` javascript -app.set('port',process.env.port || 3000); -``` - -## Screenshots - -- Fields validation -

-final-project-image -

+ ```bash + npm install + ``` -- Invalid password or email -

-final-project-image -

+5. Start the dev server: -- Successful sign in -

-final-project-image -

+ ```bash + npm run dev + ``` -- Sending token on headers + Open [http://localhost:3000](http://localhost:3000) to view it in the browser. -

-final-project-image -

+6. To compile TypeScript to JavaScript and run the project: -- Authorization + ```bash + npm run build && npm start + ``` -

-final-project-image -

+## Screenshots -## Tutorials +Basic input validation -- [JsonWebTokens #1](https://www.youtube.com/watch?v=qckBlIfOnlA) -- [JsonWebTokens #2](https://www.youtube.com/watch?v=mbsmsi7l3r4) -- [JsonWebTokens #3](https://www.youtube.com/watch?v=7nafaH9SddU) -- [Passport JWT Strategy Flow](https://www.youtube.com/watch?v=o6mSdG09yOU) +![Screenshot](https://i.imgur.com/JQD2vth.png) -## Explication +Invalid password or email -#### Route creation +![Screenshot](https://i.imgur.com/B8Mzqk5.png) -``` javascript -import { Router } from 'express'; -import { signIn, signUp } from '../controllers/user.controller'; +Successful sign in -const router = Router(); +![Screenshot](https://i.imgur.com/hJoFb4B.png) -router.post('/signup',signUp); -router.post('/signin', signIn); +Sending token on headers -export default router; -``` +![Screenshot](https://i.imgur.com/5r0cAo0.png) -#### Route controller +Authorization -``` javascript -router.get('/auth', passport.authenticate('jwt', {session: false}), (req, res) => { - res.status(200).json({msg: "Auth route succeeded"}) -}) -``` +![Screenshot](https://i.imgur.com/jcTFWIB.png) -#### Create token +## Tech Stack -``` javascript -function createToken(user:Iuser) { - return jwt.sign({id: user.id, email:user.email}, config.jwtSecret, { - expiresIn: 86400 - }) -} -``` +| Name | Description | +| ---------------------------------------------------------- | ----------------------------------------------------------- | +| [Node.js](https://nodejs.org/es/download/) | Business logic | +| [MongoDB](https://www.mongodb.com/try/download/community) | Database | +| [Express](https://expressjs.com/es/api.html) | HTTP Server | +| [TypeScript](https://www.typescriptlang.org/) | JavaScript super-set to add static code analysis | +| [JWT](https://jwt.io/) | Library to generate JWTs | +| [Mongoose](https://mongoosejs.com/docs/api.html) | ODM (Object Data Modeling) | +| [Passport JWT](https://www.npmjs.com/package/passport-jwt) | Passport strategy for authenticating with a JSON Web Token. | +| [Bcrypt](https://www.npmjs.com/package/passport-jwt) | Passport strategy for authenticating with a JSON Web Token. | -Works in this way... With JWT obviously you can generate a token for authentication, a token have some public and private information. Public info is like the algorith used to sign token or the type of token, also included something called "payload" wich is content or body of token (this includes all data registered for token). +## Lessons Learned -To generate a token we use a function from jwt moduled sign, passing a "payload" that is information of token, and a secret used to sign token. +### Route creation -Token is signed by a private key, and it is used to "decrypt" it and use to auth, passport takes his time in this, with passport-jwt we can use a function called passport.authenticate() and thats it. +```typescript +import { Router } from "express"; +import { signIn, signUp } from "../controllers/user.controller"; +const router = Router(); -## Architecture +router.post("/signup", signUp); +router.post("/signin", signIn); -- [MVC](https://si.ua.es/es/documentacion/asp-net-mvc-3/1-dia/modelo-vista-controlador-mvc.html) +export default router; +``` -## Modules used +### Route controller -- [bcrypt](https://github.com/kelektiv/node.bcrypt.js) +```typescript +router.get( + "/auth", + passport.authenticate("jwt", { session: false }), + (req, res) => { + res.status(200).json({ msg: "Auth route succeeded" }); + } +); +``` -- [cors](https://github.com/expressjs/cors) +### Create token -- [express](https://github.com/expressjs/express) +```typescript +function createToken(user: Iuser) { + return jwt.sign({ id: user.id, email: user.email }, config.jwtSecret, { + expiresIn: 86400, + }); +} +``` -- [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) +Works in this way... With JWT obviously you can generate a token for authentication, a token can hold public data in a stateless way. Public info is like the algorithm used to sign token or the type of token, also included something called "payload" which is content or body of token (this includes all data registered for token). -- [mongoose](https://github.com/Automattic/mongoose) +To generate a token we use a function from jwt module called sign, passing a "payload" that is information that token will save, and a secret used to sign the token. -- [morgan](https://github.com/expressjs/morgan) +Token is signed by a private key, and with the same key we can check if token is valid and use it to authenticate an user, passport takes his time in this, with passport-jwt we can use a function called passport.authenticate() which is a middleware that handles all the logic from getting the token from auth header to validate it and attach the token payload to the request object of express. -- [passport](https://github.com/jaredhanson/passport) +## Roadmap -- [passport-jwt](https://github.com/mikenicholson/passport-jwt) \ No newline at end of file +- [x] App functionality +- [ ] Testing +- [ ] Hosting, domain, etc. +- [ ] CI/CD diff --git a/package-lock.json b/package-lock.json index 5f243be..ac0050c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -225,9 +225,9 @@ } }, "bl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", - "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1"