Spring Security 6 with ReactJS, OAuth2, JWT | Real Project
Spring Security 6 with ReactJS, OAuth2, JWT | Real Project
In this tutorial, we’ll create a full-stack project that uses Spring Security 6 on the backend, ReactJS on the frontend, and integrates OAuth2 with JWT for secure authentication. This combination is highly effective for modern web applications, ensuring robust security while keeping a seamless user experience.
Buy Now
Key Technologies:
- Spring Security 6: For securing your backend application.
- ReactJS: A popular front-end JavaScript library for building user interfaces.
- OAuth2: An industry-standard protocol for authorization.
- JWT (JSON Web Token): A compact, URL-safe means of representing claims to be transferred between two parties.
By the end of this project, you’ll have a comprehensive understanding of how to build a secure system that handles authentication using these modern technologies.
Project Setup
1. Backend - Spring Boot with Spring Security 6
To start, set up a Spring Boot application. Spring Boot makes it easy to create stand-alone applications that run on their own server with minimal configuration.
Steps:
- Create a new Spring Boot project: You can use the Spring Initializer (https://start.spring.io/) to bootstrap your project.
- Include the following dependencies:
- Spring Web
- Spring Security
- OAuth2 Resource Server
- Spring Boot DevTools (optional, for development)
- Spring Data JPA (for database interaction)
- H2 (or any database you prefer)
Example pom.xml
Dependencies:
xml<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
Once the dependencies are set up, let’s move on to configuring Spring Security for OAuth2 and JWT.
2. Security Configuration
Spring Security 6 offers an easy way to integrate OAuth2 and JWT authentication. To begin, we need to configure Spring Security to handle OAuth2 and JWT.
Create a class named SecurityConfig
and annotate it with @Configuration
and @EnableWebSecurity
to enable web security.
java@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
}
}
In this configuration, the /api/auth/**
endpoint is left open for user authentication, while other routes are protected, requiring a valid JWT token.
3. JWT Utility Class
To generate and validate JWT tokens, create a utility class named JwtUtils
.
javaimport io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtUtils {
private final String SECRET_KEY = "your_secret_key_here";
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10 hours
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public Claims extractClaims(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}
public boolean isTokenValid(String token, String username) {
String extractedUsername = extractClaims(token).getSubject();
return (extractedUsername.equals(username) && !isTokenExpired(token));
}
private boolean isTokenExpired(String token) {
return extractClaims(token).getExpiration().before(new Date());
}
}
This class generates and validates JWT tokens using a secret key. Replace your_secret_key_here
with a secure key of your choice.
Frontend - ReactJS
For the frontend, we’ll use ReactJS to build a simple user interface that communicates with the Spring Boot backend.
1. Setting Up ReactJS
If you don’t already have a ReactJS project, create one using the following command:
bashnpx create-react-app oauth-jwt-client
Navigate to the project directory and install the necessary packages.
2. Setting Up Axios for HTTP Requests
To communicate with the backend, install Axios in your ReactJS project.
bashnpm install axios
Create an api.js
file to configure Axios for making requests to the Spring Boot API.
javascriptimport axios from 'axios';
const API_URL = 'http://localhost:8080/api';
const api = axios.create({
baseURL: API_URL,
headers: {
'Content-Type': 'application/json'
}
});
export default api;
This API instance will be used to make authenticated and unauthenticated requests.
3. React Components for Authentication
Create a Login
component that will allow users to log in and receive a JWT token.
javascriptimport React, { useState } from 'react';
import api from './api';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await api.post('/auth/login', { username, password });
localStorage.setItem('token', response.data.token); // Save token
alert('Login successful!');
} catch (error) {
console.error('Login failed:', error);
alert('Login failed. Please check your credentials.');
}
};
return (
<div>
<h2>Login</h2>
<form onSubmit={handleSubmit}>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Username"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button type="submit">Login</button>
</form>
</div>
);
};
export default Login;
This component sends the username and password to the backend and, upon successful authentication, stores the JWT token in localStorage
.
4. Making Authenticated Requests
To make authenticated requests, you need to attach the JWT token to the Authorization header.
javascriptconst token = localStorage.getItem('token');
const response = await api.get('/protected-route', {
headers: {
Authorization: `Bearer ${token}`
}
});
This way, you can call protected routes in your backend by attaching the JWT token to your requests.
OAuth2 Integration
If you want to integrate OAuth2 providers like Google or GitHub, Spring Security 6 makes it easy. You’ll need to register your app with the provider (e.g., Google Cloud Console) and then configure your Spring Security to handle OAuth2 login.
Here’s an example configuration for Google OAuth2 in application.yml
:
yamlspring:
security:
oauth2:
client:
registration:
google:
client-id: your-client-id
client-secret: your-client-secret
scope: profile, email
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
authorization-grant-type: authorization_code
client-name: Google
Spring Boot will automatically handle the OAuth2 flow and exchange the authorization code for an access token. You can then use the token to authenticate and interact with your React frontend.
Conclusion
By combining Spring Security 6, OAuth2, JWT, and ReactJS, you can build a secure and scalable web application. This stack is widely used in modern web development and ensures that your app can handle user authentication efficiently while providing a great user experience.
This project gives you a solid foundation to expand upon, whether adding more sophisticated features or integrating with external OAuth2 providers like Google or GitHub. Now you're ready to enhance your project further with more advanced security policies, social logins, or role-based access control.
Post a Comment for "Spring Security 6 with ReactJS, OAuth2, JWT | Real Project"