Hello! In this blog post, we will take a detailed look at how to implement login and logout functionalities using JSON Web Token (JWT) in the backend development process with Spring Boot. Authentication and authorization are crucial elements in web application development, and JWT helps to manage them effectively. In this tutorial, we will explain the concept of JWT, Spring Boot configuration, how to add dependencies, and more step by step.
1. What is JWT?
JWT stands for JSON Web Token, a standard for securely transmitting user authentication information. JWT consists of three parts:
- Header: Contains information about the type of token and the hashing algorithm used.
- Payload: Includes claims such as user information. This claim can contain public information (information needed for API calls).
- Signature: A signature created using a secret key based on the header and payload information. This ensures the integrity of the data and is used to verify if someone has forged the token.
The greatest advantage of JWT is its stateless property. As there is no need for the server to maintain session state, it provides excellent scalability and performance.
2. Creating a Spring Boot Project
Let’s create a new project using Spring Boot. First, visit Spring Initializr (https://start.spring.io/). Apply the following settings to create the project:
- Project: Maven Project
- Language: Java
- Spring Boot: 2.6.0 (select the latest version)
- Group: com.example
- Artifact: jwt-demo
- Dependencies: Spring Web, Spring Security, Spring Data JPA, H2 Database
After creating the project, open it in your IDE and set up the necessary directory structure.
3. Adding Dependencies
First, add the required dependencies to the pom.xml
file:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jwt</artifactId>
<version>0.9.1</version>
</dependency>
Additionally, Spring Security and Data JPA are already included, so no extra dependencies are needed. The H2 database can be useful for development and testing environments.
4. Configuring Spring Security
We need to configure Spring Security to use JWT. First, create the SecurityConfig
class:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@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();
}
}
In the above configuration, all users can access the /api/auth/**
path. All other requests require authentication.
5. Generating and Validating JWT
Let’s write a class to generate and validate JWT. Define the necessary methods here:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Service;
import java.util.Date;
@Service
public class JwtUtil {
private String secretKey = "YourSecretKey"; // The secret key should be managed securely and not exposed
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10 hours
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
public boolean validateToken(String token, String username) {
final String extractedUsername = extractUsername(token);
return (extractedUsername.equals(username) && !isExpired(token));
}
public String extractUsername(String token) {
return extractAllClaims(token).getSubject();
}
private Claims extractAllClaims(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
}
private boolean isExpired(String token) {
return extractAllClaims(token).getExpiration().before(new Date());
}
}
The above JwtUtil
class contains methods for token generation, validation, and username extraction.
6. Implementing Authentication and Logout
Now let’s write a controller to handle authentication and logout. Create the AuthController
class:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public ResponseEntity login(@RequestBody AuthRequest authRequest) {
// Add user authentication logic here
String token = jwtUtil.generateToken(authRequest.getUsername());
return ResponseEntity.ok(token);
}
@PostMapping("/logout")
public ResponseEntity logout() {
// Add logic to blacklist JWT, etc.
return ResponseEntity.ok("Logout successful");
}
}
In the above code, AuthRequest
is a DTO class that contains the username and password, and the user authentication logic should be implemented in detail. Typically, it checks the authentication information in the database.
7. Final Testing
Now that we have completed all the configurations, you can test the API using a tool like Postman:
- Login:
POST /api/auth/login
- Logout:
POST /api/auth/logout
By passing the username and password in the request body of the login API, you will successfully receive a JWT in return. The returned JWT should be included in the Authorization
header for subsequent API calls.
8. Conclusion
We explored the implementation of login and logout functionalities based on JWT using Spring Boot. Authentication and authorization are crucial aspects of web application development, and JWT helps manage these conveniently and securely. Additional features to consider include handling JWT blacklist and implementing refresh tokens.
I hope this tutorial has been helpful for your Spring Boot backend development. For more information and resources, you can check the official documentation and community. Thank you!