Login App with CSRF protection – Implement authentication in ReactJS using secure REST API – Part 3

Today we’ll show you how to create a login application with XSS and CSRF protection. As you know we have divided the whole series in three parts and it’s the last part of the article.

Login App with CSRF protection – Implement authentication in ReactJS using secure REST API, Build a React.js Application with User Login and Authentication, login form in react js using localStorage, cookie and redux store, Authentication For Your React and Express Application with JWT access token and refresh token, Protected routes and Authentication with React and Node.js, Authentication using JWT from ReactJS Single Page Application, Prevent Cross-site scripting (XSS), Cross-site request forgery (CSRF/XSRF) attack.

If you have seen the previous articles of the ReactJS where we talked about the authentication in ReactJS using Node.js API. So additionally, we will let you know the secure way to implement authentication in ReactJS in today’s article.

We planned to divide this article into three parts.

Way to create login application in ReactJS using secure REST API

  1. Create secure REST API in Node.js
  2. Setup react app
  3. Create react components
  4. Implement react router
  5. Add services to call API
  6. Implement redux
  7. Create route guard
  8. Connect components to the redux store
  9. Output

1. Create secure REST API in Node.js

To create a secure login application, first we have to create a REST API so we can consume it into the react application. We have already created the REST API in Node.js for authentication. You can create REST API in any backend technologies.

If you don’t want to create an API then download the source code and run the project.

2. Setup react app

Let’s setup the basic react application using create-react-app to implement the authentication in ReactJS. In this article, mostly we’ll use the React Hooks.

Check out the following file structure of the react application that you should prefer.

Login App - File structure - Clue Mediator
Login App – File structure – Clue Mediator

3. Create react components

In this article, we’ll create components like Login & Dashboard and some styles in the css file. You can create more than it but for the demo purposes we have considered only two components.

  • Login component – It will contain a simple login form where we can call the API to validate the user. On successful authentication, we will redirect you to the Dashboard component.
  • Dashboard component – It’s accessible only for the authenticated user. In this page, we will call one more API to get the user list with the help of the access token. We will have one more button to manage the logout.

App.js

pages/Login.js

pages/Dashboard.js

index.css

4. Implement react router

In the next step, we have to implement a routing in the react application. We would recommend you to check this link to implement routing in the login application.

After implementing routing in the react app, your App.js file will look like this.

App.js

5. Add services to call API

In the upcoming steps, we have to call an API to implement authentication. If you don’t know about the API integration then refer to this link: API calls with React Hooks.

Let’s create services to manage an API call. We will divide these services in two parts.

Here we will use the axios npm package so it will automatically read the XSRF token from the cookie and append it in the request of the API call to avoid the CSRF attack. If the XSRF token is not present in the request header then the private route won’t be accessible from the server.

services/auth.js

services/user.js

6. Implement redux

We’ll assume that you already know about the redux and redux-thunk. If you don’t know how to set up a redux store then kindly refer to the following articles for more understanding.

If you have read the first article about the understanding of the authentication where we have explained the reason to use redux.

We’ll manage the authentication user details in the redux store along with the access token and expiry time to avoid the Cross-site scripting (XSS) attack and refresh token token and XSRF token will be managed in cookie to avoid Cross-site request forgery (CSRF/XSRF) attack.

In the current application, we’ll manage only the authentication reducer in the redux store. Check out the below state to be considered as an initial state in the auth reducer.

For your understanding, we have written the short description within the code.

We’ll also consider the several types of actions for the redux store.

  • VERIFY_TOKEN_STARTED – We can use it when the verifyTokenService API call will be started.
  • VERIFY_TOKEN_END – We will make this call when the verifyTokenService process is over.
  • USER_LOGIN_STARTED – We’ll use it when the userLoginService starts.
  • USER_LOGIN_FAILURE – This action type will be used on failure of the userLoginService API call.
  • VERIFY_USER_SUCCESS – This type will help us to manage the response on successful logged-in.
  • USER_LOGOUT – Use it to manage the user logout functionality.

Let’s set up a redux in application by adding the several files.

actions/actionTypes.js

actions/authActions.js

In the next steps, we’ll create async actions to manage verification of token, user login and user logout.

asyncActions/authAsyncActions.js

Let’s create a reducer file to add it to the redux store.

reducers/authReducer.js

reducers/index.js

store.js

index.js

7. Create route guard

Here we’ll create two types of the route guards for managing the redirection. One will be used for private routes and another one will be used for public routes.

routes/PrivateRoute.js

routes/PublicRoute.js

Here we used the isAuthenticated flag from the redux store to manage application routing.

8. Connect components to the redux store

It’s the last step to connect components to the redux store. We will use the useSelector & useDispatch hooks from the react redux.

App.js

Now let’s talk about the Login component.

pages/Login.js

So at last, we will work on the Dashboard component.

pages/Dashboard.js

9. Output

Let’s run this project and see the output. You have to run the node server that we describe in the previous article to enable the API.

Output - Login App with CSRF protection - Implement authentication in ReactJS using secure REST API - Clue Mediator
Output – Login App with CSRF protection – Implement authentication in ReactJS using secure REST API – Clue Mediator

Demo & Source Code

Github Repository StackBlitz Project

You may also like...

8 Responses

  1. Thomas Jennings says:

    What keeps someone from sniffing username and password in axios.post(${API_URL}/users/signin, { username, password }); ?

    • Clue Mediator says:

      Hello Thomas,
      If it’s easily possible then no one will use REST API. If you have any idea about it then please share with us.

      We will enjoy learning new things. 🙂
      Thank you!

  2. Thomas Jennings says:

    Thanks for the response. And also thanks very much for all these articles! After doing some more reading I guess the best answer to my question would be to make sure to use https, that way the username and password would be encrypted going across the wire.

  3. Col says:

    As the security related infos are basically stored inside Redux store, the token only persists as long as the session (bowser) is running. However, when the browser is closed, all the infos are gone thus, If I want to make ‘stayed sign in’ feature, do I have to store the Token info inside Cookies as well as helper functions or other means to refresh the token outside of the browser

    • Clue Mediator says:

      Hey Col,

      You can see here, we are storing the refresh token in cookies to perform the silent authentication.

      So when we are reloading the page then we will use these all details to get the basic user information before rendering the component. Please check out the working demo and output for more details.

      Feel free to share your thoughts.

      Subscribe us for weekly updates or like and follow us for regular updates.

      Happy Coding..!!

  4. Romil LODAYA says:

    This post helps a lot. I have two questions
    1 – How to handle verifyTokenTimer() commonly when we have more pages. As we are making repetitive code in each file.
    2 – When I am calling login it gives me a response in the Network tab with Set-Cookie but not in COOKIE inside the application tab.

    • Clue Mediator says:

      Hello Romil,
      Please find your answer below.
      Ans1 – You can use that method in the root level of the private route or you can create a custom effect and use it at multiple places.
      Ans2 – Can you please clone the repository that we have provided and check it in your local system?

      Subscribe us for weekly updates or like and follow us for regular updates.

      Thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *