# Authentication
Refer to the lesson for the code syntax.
## Backend
### Models
- A user should be able to input something unique to be able to sign up and log in.
- We can rely on email or username.
- We will store a hashed-salted password in our User collection in the database.
### Sign up
- This is your first encounter with a new user.
- We need to get the user email or username, password and all the informations necessary in your application.
- Verify that the informations provided are valid / safe based on your criterions
- The unique username/mail, should be unique (and valid), you should not be able to find an existing entry in your database.
- The password should be safe.
- If those criterions are passed, generate a salt using bcrypt, then generate a hashed version of the user password.
- Create the user in your database.
### Log in
- The user came back. He/She likes your website.
- Still, we need them to prove their identity, we need their username/email and a password.
- If we can't find anyone with this username/email, the user provided some wrong credential, warn them.
- If we find someone, we need to check if the password they provided match the one hashed in our database.
- If it does not, warn them.
- Everything looks fine, we need to generate a token so that the user can remain logged in.
- A token is composed of 3 elements:
- Payload: The id of the user or it's username. Avoid Sensible informations
- Secret: A random secret string unique to our server
- Options: The encryption used and the expiration time.
- Send that token to the client.
### How does the Token is sent from the client?
#### Postman
- We recover the token from logging in and put it in the Authorization headers of the Request.
- It is generally prefixed with `Bearer YourTokenHere`
#### Frontend
- When logging in the frontend (React) receive the token and we store it in the localStorage.
- When we make a request to the backend on a protected route, we need to send the token with the request.
### How do I protect a route?
- You need to create a middleware
- Here is a breakdown of the isAuthenticated middleware seen in class:
- Get the token from the authorization headers.
- No token ? Not allowed.
- Verify the token using `jsonwebtoken` package.
- Verify will throw an Error if the token is not valid.
- **Save the user id located in the payload on the Request object**.
- next()
#### Usage of a middleware to protect a route.
- We can do some wide protection or individual protection.
**Wide protection**
We use the middleware in the global scope, all the routes below it are now protected.
```javascript=
// Not protected
router.use('/auth', ...)
router.use('/public', ...)
// middleware
router.use(isAuthenticated)
// Need to be authenticated
router.use('/user', ...)
// ...
router.use(isAdmin)
// Need to be an admin
router.use('/dashboard', ...)
// ...
```
**Individual protection**
Some routes might need some punctual protection.
```javascript=
router.post("/vote", isAdminOrAlumni, ...)
```
> An admin or an Alumni can post on this route, a student cannot.
### Route usage
- Knowing who the logged in user is allow us sometime to not need some extra informations.
- To update a ressource, we used to need the id of the ressource which we wanted to update, typically in the `params` of the url.
- Usually a user can only update something which belong to him. By going through the isAuthenticated middleware we know who the user is.
**Before**
```javascript=
router.patch("/profile/:id", isAuthenticated, async (req, res, next) => {
try {
User.findByIdAndUpdate(req.params.id, ...)
// ...
} catch (error) {
next(error)
}
})
```
> Anyone with a lot of time to loose can update any profile.
**After**
```javascript=
router.patch("/profile", isAuthenticated, async (req, res, next) => {
try {
User.findByIdAndUpdate(req.user._id, ...)
// ...
} catch (error) {
next(error)
}
})
```
> The user can only update the profile associated to his token (statistically, his profile then.)