Learning JWT Part 10 - Protecting routes & log out user
===

---
###### tags: `JWT`
## What is middleware?
**Middleware** functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle.
> Reference: [Using middleware](https://expressjs.com/en/guide/using-middleware.html#using-middleware)
#### What does middleware have to do with route protecting?
We need to implement some functionality in the middle of **login** and redirect user to specific page, therefore we need some functions to check if user has token, if not, then we shall redirect user to login page.
## Create middleware function to check if token exists.
> Reference: [jwt.verify(token, secretOrPublicKey, [options, callback])](https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback)
Method we will be using here is:
- `jwt.verify()`
The flow would be:
- Create a middleware folder(optional)
- Create `authMiddlware.js` inside the folder.
- Grab token from browser.
- If there's a token, use `jwt.verify` to verify the token.
- if there' an error, redirect user to `login` page.
- if not, invoke `next()`
- If there's no token, redirect user to `login` page.
```javascript=
const env = require('dotenv').config();
const jwt = require('jsonwebtoken');
const requireAuth = (req, res, next) => {
// get token from browser
const token = req.jwt.cookies;
if (token) {
// Verify token
jwt.verify(token, process.env.JWT_SECERT, (err, decodedToken) => {
if (err) {
res.redirect('/login');
} else {
next();
}
})
} else {
res.redirect('/login');
}
}
```
Apply the `authMiddleware.js` function to `app.js`
```javascript=
// app.js
// routes
app.get("/", (req, res) => res.render("home"));
app.get("/smoothies", requireAuth, (req, res) => res.render("smoothies"));
app.use(authRoutes);
```
We can apply `requireAuth` on route homepage as well, then user won't even see the homepage without logging in.
```javascript=
// routes
app.get("/", requireAuth, (req, res) => res.render("home"));
app.get("/smoothies", requireAuth, (req, res) => res.render("smoothies"));
app.use(authRoutes);
```

---
## Log out user
For log out, we can't delete token from server side, but we can swape a token to an empty string.
First, let's create a route that handles logout.
```javascript=
// in side routes folder
// authRoutes.js
const { Router } = require("express");
const authController = require("../controllers/authController");
const router = Router();
// Create routes here
router.get("/signup", authController.signup_get);
router.post("/signup", authController.signup_post);
router.get("/login", authController.login_get);
router.post("/login", authController.login_post);
router.get("/logout", authController.logout_get);
module.exports = router;
```
Import to `authController.js`
```javascript!
// authController.js
...
module.exports.logout_get = (req, res) => {
res.cookie("jwt", "", { maxAge: 1 });
res.redirect("/login");
};
```
