Spring Boot + React: JWT Authentication with Spring Security

In this tutorial, we will learn how to build a full stack Spring Boot + React.js Authentication example. The back-end server uses Spring Boot with Spring Security for JWT authentication and Spring Data JPA for interacting with database. The front-end will be created with React, React Router & Axios. We’ll also use Bootstrap and perform Form validation.

Related Post:
Spring Boot + React + MySQL: CRUD example with REST APIs


JWT (JSON Web Token)

Nowaday, JWT is popular for Authentication and Information Exchange. Instead of creating a Session (Session-based Authentication), Server encodes data into a JSON Web Token and send it to the Client. The Client saves the JWT, then every Request from Client to protected routes or resources should be attached that JWT (commonly at header). The Server will validate that JWT and return the Response.

in-depth-introduction-jwt-token-based-authentication

Comparing with Session-based Authentication that need to store Session on Cookie, the big advantage of JWT (Token-based Authentication) is that we store the Token on Client side: Local Storage for Browser, Keychain for IOS and SharedPreferences for Android… So we don’t need to build another backend project that supports Native Apps or an additional Authentication module for Native App users.

There are three important parts of a JWT: Header, Payload, Signature. Together they are combined to a standard structure: header.payload.signature.

The Client typically attact JWT in Authorization header with Bearer prefix:

Authorization: Bearer [header].[payload].[signature]

For more details, you can visit:
In-depth Introduction to JWT-JSON Web Token

Spring Boot React Authentication example

It will be a full stack, with Spring Boot for back-end and React.js for front-end. The system is secured by Spring Security with JWT Authentication.

  • User can signup new account, login with username & password.
  • Authorization by the role of the User (admin, moderator, user)

Here are the screenshots of our system:

– Anyone can access a public page before logging in:

spring-boot-react-authentication-jwt-example-public

– A new User can signup:

spring-boot-react-authentication-jwt-example-signup

– Form Signup validation:

spring-boot-react-authentication-jwt-example-signup-form-validation

– After signup is successful, User can login:

spring-boot-react-authentication-jwt-example-login

– After login, App directs the User to Profile page:

spring-boot-react-authentication-jwt-example-profile

– UI for Moderator login (the navigation bar will change by authorities):

spring-boot-react-authentication-jwt-example-authorization

– If a User who doesn’t have Admin role tries to access Admin/Moderator Board page:

spring-boot-react-authentication-jwt-example-unauthorization

Flow for User Registration and User Login

The diagram shows flow for User Registration process and User Login process.

spring-boot-react-authentication-jwt-example-flow

There are 2 endpoints for authentication:

  • api/auth/signup for User Registration
  • api/auth/signin for User Login

If Client wants to send request to protected data/endpoints, it add legal JWT to HTTP Authorization Header.

Spring Boot & Spring Security for Back-end

Overview

Our Spring Boot Application can be summarized in the diagram below:

spring-boot-authentication-spring-security-architecture

Let me explain it.

Spring Security

WebSecurityConfigurerAdapter is the crux of our security implementation. It provides HttpSecurity configurations to configure cors, csrf, session management, rules for protected resources. We can also extend and customize the default configuration that contains the elements below.

UserDetailsService interface has a method to load User by username and returns a UserDetails object that Spring Security can use for authentication and validation.

UserDetails contains necessary information (such as: username, password, authorities) to build an Authentication object.

UsernamePasswordAuthenticationToken gets {username, password} from login Request, AuthenticationManager will use it to authenticate a login account.

AuthenticationManager has a DaoAuthenticationProvider (with help of UserDetailsService & PasswordEncoder) to validate UsernamePasswordAuthenticationToken object. If successful, AuthenticationManager returns a fully populated Authentication object (including granted authorities).

OncePerRequestFilter makes a single execution for each request to our API. It provides a doFilterInternal() method that we will implement parsing & validating JWT, loading User details (using UserDetailsService), checking Authorizaion (using UsernamePasswordAuthenticationToken).

AuthenticationEntryPoint will catch unauthorized error and return a 401 when Clients access protected resources without authentication.

Repository contains UserRepository & RoleRepository to work with Database, will be imported into Controller.

Controller receives and handles request after it was filtered by OncePerRequestFilter.

AuthController handles signup/login requests

TestController has accessing protected resource methods with role based validations.

Technology

To implement the server with concept above, we will use:
– Java 8
– Spring Boot 2 (with Spring Security, Spring Web, Spring Data JPA)
– jjwt 0.9.1
– PostgreSQL/MySQL
– Maven 3.6.1

Project Structure

The structure of Spring Boot back-end project is pretty complicated:

spring-boot-react-authentication-jwt-example-server-project-structure

You can see that there are 5 packages:

security: we configure Spring Security & implement Security Objects here.

  • WebSecurityConfig extends WebSecurityConfigurerAdapter
  • UserDetailsServiceImpl implements UserDetailsService
  • UserDetailsImpl implements UserDetails
  • AuthEntryPointJwt implements AuthenticationEntryPoint
  • AuthTokenFilter extends OncePerRequestFilter
  • JwtUtils provides methods for generating, parsing, validating JWT

controllers handle signup/login requests & authorized requests.

  • AuthController: @PostMapping(‘/signin’), @PostMapping(‘/signup’)
  • TestController: @GetMapping(‘/api/test/all’), @GetMapping(‘/api/test/[role]’)

repository has intefaces that extend Spring Data JPA JpaRepository to interact with Database.

  • UserRepository extends JpaRepository
  • RoleRepository extends JpaRepository

models defines two main models for Authentication (User) & Authorization (Role). They have many-to-many relationship.

  • User: id, username, email, password, roles
  • Role: id, name

payload defines classes for Request and Response objects

We also have application.properties for configuring Spring Datasource, Spring Data JPA and App properties (such as JWT Secret string or Token expiration time).

Implementation

You can find step by step to implement this Spring Boot – Spring Security App in the post:
Secure Spring Boot App with Spring Security & JWT Authentication

And this is for working with MongoDB:
Spring Boot, MongoDB: JWT Authentication with Spring Security

React, React Router for Front-end

Overview

Let’s look at the diagram below.

spring-boot-react-authentication-jwt-example-react-components

– The App component is a container with React Router (BrowserRouter). Basing on the state, the navbar can display its items.

Login & Register components have form for data submission (with support of react-validation library). They call methods from auth.service to make login/register request.

auth.service methods use axios to make HTTP requests. Its also store or get JWT from Browser Local Storage inside these methods.

Home component is public for all visitor.

Profile component displays user information after the login action is successful.

BoardUser, BoardModerator, BoardAdmin components will be displayed by state user.roles. In these components, we use user.service to access protected resources from Web API.

user.service uses auth-header() helper function to add JWT to HTTP header. auth-header() returns an object containing the JWT of the currently logged in user from Local Storage.

Technology

We’re gonna use these modules:

  • React 16
  • react-router-dom 5
  • axios 0.19.2
  • react-validation 3.0.7
  • Bootstrap 4
  • validator 12.2.0

Project Structure<

This is folders & files structure for this React application:

react-jwt-authentication-project-structure

With the explanation in diagram above, you can understand the project structure easily.

Implementation

You can find step by step to implement this React App in the post:
React JWT Authentication (without Redux) example

Conclusion

Now we have an overview of Spring Boot React Authentication example using JWT, Spring Security along with flow for login and registration.

We also take a look at Spring Boot server architecture for JWT Authentication using Spring Sercurity & Spring Data JPA, as well as React.js project structure (React Router, Axios, without Redux) for building a front-end app working with JWT.

Next tutorials will show you more details about how to implement this interesting system:
– Back-end:

– Front-end: React JWT Authentication (without Redux) example

Happy learning, see you again!

Further Reading

Leave a Reply

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