Skip to content

Commit

Permalink
docs: 📝 Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
AloisCRR committed May 16, 2021
1 parent bbf6651 commit 47bac99
Showing 1 changed file with 116 additions and 84 deletions.
200 changes: 116 additions & 84 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,130 +1,162 @@
## 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);
```
```bash
npm install
```

## Screenshots
5. Start the dev server:

- Fields validation
<p align='center'>
<img src='https://i.imgur.com/JQD2vth.png' alt='final-project-image'>
</p>
```bash
npm run dev
```

- Invalid password or email
<p align='center'>
<img src='https://i.imgur.com/B8Mzqk5.png' alt='final-project-image'>
</p>
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

- Successful sign in
<p align='center'>
<img src='https://i.imgur.com/hJoFb4B.png' alt='final-project-image'>
</p>
6. To compile TypeScript to JavaScript and run the project:

- Sending token on headers
```bash
npm run build && npm start
```

<p align='center'>
<img src='https://i.imgur.com/5r0cAo0.png' alt='final-project-image'>
</p>
## API Reference

- Authorization
#### Sign up or register

<p align='center'>
<img src='https://i.imgur.com/jcTFWIB.png' alt='final-project-image'>
</p>
```http
POST /signup
```

## Tutorials
| Body | Type | Description |
| :--------- | :------- | :------------------------------- |
| `email` | `string` | **Required**. User email address |
| `password` | `string` | **Required**. Account password |

- [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)
#### Sign in or login

## Explication
```http
POST /signin
```

#### Route creation
| Body | Type | Description |
| :--------- | :------- | :------------------------------- |
| `email` | `string` | **Required**. User email address |
| `password` | `string` | **Required**. Account password |

``` javascript
import { Router } from 'express';
import { signIn, signUp } from '../controllers/user.controller';
```http
GET /auth
```

const router = Router();
| Headers | Type | Description |
| :--------------- | :---- | :-------------------------------------------- |
| `Authentication` | `JWT` | **Required**. Jwt gived on sign in or sign up |

router.post('/signup',signUp);
router.post('/signin', signIn);
## Screenshots

export default router;
```
Basic input validation

#### Route controller
![Screenshot](https://i.imgur.com/JQD2vth.png)

``` javascript
router.get('/auth', passport.authenticate('jwt', {session: false}), (req, res) => {
res.status(200).json({msg: "Auth route succeeded"})
})
```
Invalid password or email

#### Create token
![Screenshot](https://i.imgur.com/B8Mzqk5.png)

``` javascript
function createToken(user:Iuser) {
return jwt.sign({id: user.id, email:user.email}, config.jwtSecret, {
expiresIn: 86400
})
}
```
Successful sign in

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).
![Screenshot](https://i.imgur.com/hJoFb4B.png)

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.
Sending token on headers

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.
![Screenshot](https://i.imgur.com/5r0cAo0.png)

Authorization

## Architecture
![Screenshot](https://i.imgur.com/jcTFWIB.png)

- [MVC](https://si.ua.es/es/documentacion/asp-net-mvc-3/1-dia/modelo-vista-controlador-mvc.html)
## Tech Stack

## Modules used
| 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. |

- [bcrypt](https://github.com/kelektiv/node.bcrypt.js)
## Lessons Learned

- [cors](https://github.com/expressjs/cors)
### Route creation

- [express](https://github.com/expressjs/express)
```typescript
import { Router } from "express";
import { signIn, signUp } from "../controllers/user.controller";
const router = Router();
router.post("/signup", signUp);
router.post("/signin", signIn);
export default router;
```
### Route controller
```typescript
router.get(
"/auth",
passport.authenticate("jwt", { session: false }),
(req, res) => {
res.status(200).json({ msg: "Auth route succeeded" });
}
);
```
### Create token
```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)
- [x] App functionality
- [ ] Testing
- [ ] Hosting, domain, etc.
- [ ] CI/CD

0 comments on commit 47bac99

Please sign in to comment.