Clue Mediator

Login App with CSRF protection - Understanding authentication using JWT access token and refresh token - Part 1

📅April 22, 2020

In this article, we’ll show you how to implement secure login authentication using JWT access token and refresh token with CSRF protection.

Previously we have written an article that explains how to implement authentication in React App using Node.js. Over there we used the `sessionStorage` to manage the token at client side and at the server side we used only access token to manage the authentication. You can get the other two articles where you can find the way to create a REST API for authentication in Node.js and create a login form in ReactJS using Node.js REST API.

As per the request of our readers, we decided to share the knowledge of the secure login application using JWT access token and refresh token with Cross-site request forgery (CSRF or XSRF) and Cross-site scripting (XSS) protection in React & Node.js.

Securely using JWTs with CSRF protection and refresh tokens in React, Angular and Node.js, The Ultimate Guide to handling JWTs on frontend clients, Add Login Using the Authorization Code Flow, Token-based API authentication with CSRF XSS protection and JWT token, angularjs token authentication example, jwt token example, jwt best practices, jwt client side api authentication, json web token example in react js, Rest API angular authentication with jwt tutorial with step by step example for beginners, Basic understanding of the auth login form application using create-react-app.

Checkout more articles on ReactJS/Node.js

What’s new in this article?

As you know we have already written an article on the Login App in which we explained all the steps in details about the authentication. But here we have added a few more features that will really help us to improve the security of the application.

At the server side (Node.js)

  • JWT access token with short expiry time to manage the authentication.
  • XSRF token for CSRF protection.
  • JWT refresh token to manage access token when it expires.
  • Manage JWT refresh token using secure and httpOnly cookie.
  • Manage XSRF token using normal cookie to avoid the CSRF attack.

At the client side (React)

  • Manage authentication using redux store.
  • Store JWT access token in redux instead of `localStorage` to avoid XSS attack.
  • Manage silent authentication with the help of the refresh token just before the access token gets expired.
  • Manage XSRF token to pass in every single request right after the successful login to avoid CSRF attack.

We planned to divide this article into three parts.

Implementation flow

In this article, we’ll explain the secure login implementation flow only.

For a login application we will use React as a frontend application. You can use any single page application (SPA) for client application. As a backend application we will create a secure REST API in Node.js.

Key part of the implementation of secure login application

  • Access token:

    • Create access token using JWT to manage the API authentication.
    • Set a short expiry time like 15 mins for access token.
    • Return the access token in API response. At the other end we will use it to manage the private/secure REST API.
    • No need to store access tokens into the database at the backend side for authentication. We will directly verify it using the JWT package.
    • We will store it in memory instead of the `localStorage` or `sessionStorage` at the client side.
  • Refresh token:

    • Create refresh token using JWT to manage the access token.
    • We will recommend you to set a long expiry time for refresh token i.e. 30 days or 60 days.
    • Make sure we will not return the refresh token in the API response. But instead of that we have to persist it in an HttpOnly secure cookie.
    • We’ll store refresh tokens in memory or database at the backend side.
  • Silent authentication:

    • Silent authentication it’s required in below two cases.

      • As you know the access token has a short expiry time. Now it's important to renew the access token just before it expires. So the user may have an uninterrupted session.
      • Because of storing access tokens in memory at the client side, we need to maintain the login session when re-opening the browser after closing it without logout.
    • We will perform the silent authentication to renew the access token with the help of refresh token.

  • CSRF protection:

    • Cross-Site Request Forgery (CSRF or XSRF) is a one-click attack that forces logged in users to submit a request to a server without informing them. It mostly happens with the stored cookies.
    • To prevent CSRF attack, we will use XSRF token for real user identification. This token is also known as anti-CSRF token.
    • We will set XSRF token in cookie from server side and expect it to be in the header of each request.

Divide login application in two parts

  1. Node.js application (Backend)
  2. ReactJS application (Frontend)

1. Node.js Application (Backend)

Follow the below points to implement authentication API at backend side in Node.js application.

  • Use jsonwebtoken & rand-token packages - We will use jsonwebtoken npm package to create access token and refresh token. Also use the rand-token npm package to create XSRF token. Also we will use moment package to set expiry time of the token.
  • Install cookie-parser - As you know, we are planning to manage the refresh token using HttpOnly secure cookies so we need to use the cookie-parser package.
  • Install CORS - We’ll use cors package to manage the cross-origin resource sharing.
  • Create user signin API - Same as the previous login article, we have to create an API for user signin but here we have to update it slightly for a secure API.
  • Create user logout API - Additionally we need one more API to manage the user logout.
  • Create API for verify token - We need API that will help us to renew or generate access token with the help of refresh token when required.
  • Create a user list API - In this application, we will create an API that will return the list of users and it should be a private API that means we need token to access this API.
  • Implement middleware - We have to implement the middleware to verify the token and add CSRF protection for private routes.

2. ReactJS Application (Frontend)

In the frontend application, we have to work on the below points to implement a secure login app.

  • React hooks and Redux - We’ll implement this application in react with the help of react hooks and redux store.
  • Implement routing - Same as the previous login article, we need to implement routing for public and private pages.
  • Create login and dashboard pages - We’ll create a login form and dashboard pages for managing the login application. Login form will contain the simple form where we will authenticate the user and redirect them on the dashboard page. After the successful login, we have to manage the token in redux store.
  • Append token in private API - The access token should be passed in the request header of the private API. Validate the given token at the backend side and if it’s invalid then we have to manage the automatic redirection on the login page.
  • Renew access token - In the SPA, we have to re-create an access token on a web page reload to maintain the login session. The same process is required to extend the login session just before the token expires.

In the next article, we’ll implement authentication in Node.js using JWT access token and refresh token.

That’s it for today. Thanks for reading.
Like share and follow us. Happy Coding..!!