NodeJs Authentication using JWT and Cookies
JWT (JSON Web Tokens) is a great solution for API and SPA authentication which works using tokens and helps you to completely handle the authorization and authentication of your app . but there is a problem that many developers struggle with. where to store JWT token!?
you have 3 options but 2 of them is failed!
- localStorage
- sessionStorage
- Cookies
if you save your sensitive data like auth token in localStorage or sessionStorage, every javascript code in your browser can access this storage in the client-side and get this login token (XSS attacks)
so it is very important to store login token in a safe place. “Cookie” is the best option to do this for you. because it can’t be reached in front-end and it sends automatically to the server with each request.
here is an example to create a NodeJs (express) server app with JWT authentication and cookies:
1. Install the necessary packages:
npm i express body-parser cookie-parser jsonwebtoken nodemon
2. Create an app.js file like this:
const express = require("express");const app = express();const bodyParser = require("body-parser");const cookieParser = require('cookie-parser')const jwt = require("jsonwebtoken");//middlewaresapp.use(bodyParser.urlencoded({extended:true}))app.use(bodyParser.json())app.use(cookieParser())
//listenapp.listen(9000, () => {console.log("connected!");});
3. Run app
nodemon app
so it will run on port 9000.
4. Add login middleware
you may write login function in controller file (if you follow MVC pattern). here for simplicity I add all my functions to app.js.
app.post('/auth/login', (req,res)=>{
//get username from request's body, eg. from login formlet username = req.body.username/*
check username and password correctness here,
if they matched then:
/*//create jwt tokenconst token = jwt.sign({user:username},'secret_key')
//save token in cookieres.cookie('authcookie',token,{maxAge:900000,httpOnly:true}) })
so, we set a cookie named ‘authcookie’ with the value of our token generated from JWT, the expiration time of 900000 sec and httpOnly:true to secure it.
then each request from client to the server has this token.
we should check this token when user needs access to sensitive data (eg. admin panel)
5. Authorize user token
you should set authorization level in middleware you want to protect. for example, we want to protect our /api route.
first, we should write a function which checks cookie:
function checkToken (req, res) {
//get authcookie from requestconst authcookie = req.cookies.authcookie
//verify token which is in cookie valuejwt.verify(authcookie,"secret_key",(err,data)=>{ if(err){ res.sendStatus(403) }
else if(data.user){ req.user = data.user next()}}
then in ‘/api’ middleware call the function:
app.get('/api', checkToken , (req,res)=>{/*if checkToken function succeed, api reach this block
you can do whatever you want, also you can access to req.user which sent from checkToken function
*/})
enjoy it!