JSON Web Token (JWT) is a compact, URL-safe token format used for securely transmitting information between parties. It is commonly used for authentication and authorization in modern web applications. A JWT is composed of three parts:
- Header: Contains metadata, typically the algorithm used for signing the token.
- Payload: Contains the claims or data (e.g., user information).
- Signature: Ensures that the token has not been tampered with.
JWT allows for stateless authentication, meaning the server does not need to store session information. After the user logs in, the server sends a JWT to the client, which can be used for subsequent requests. This improves scalability and security by eliminating the need for server-side session management.
Setting Up JWT with Spring Boot
Here’s how you can implement JWT in a Spring Boot application:
Add Dependencies: You will need the following dependencies in your pom.xml
:
1 2 3 4 5 |
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.11.5</version> </dependency> |
Create a Utility Class for JWT Creation and Validation: This class handles the creation and validation of the JWT.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import io.jsonwebtoken.*; import java.util.Date; public class JwtTokenUtil { private String secretKey = "mySecretKey"; // Use a stronger key in production! // Generate JWT token public String generateToken(String username) { return Jwts.builder() .setSubject(username) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1 hour .signWith(SignatureAlgorithm.HS256, secretKey) .compact(); } // Validate JWT token public boolean validateToken(String token) { try { Jwts.parser() .setSigningKey(secretKey) .parseClaimsJws(token); return true; } catch (JwtException e) { return false; // Invalid token } } // Get the username from the token public String getUsernameFromToken(String token) { return Jwts.parser() .setSigningKey(secretKey) .parseClaimsJws(token) .getBody() .getSubject(); } } |
Implement JWT Authentication Filter: This filter intercepts HTTP requests to check for a valid JWT in the Authorization header.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter("/api/*") public class JwtAuthenticationFilter implements Filter { private JwtTokenUtil jwtTokenUtil = new JwtTokenUtil(); @Override public void doFilter(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response, FilterChain chain) throws IOException, ServletException { String token = ((HttpServletRequest) request).getHeader("Authorization"); if (token != null && token.startsWith("Bearer ")) { token = token.substring(7); // Remove "Bearer " prefix if (jwtTokenUtil.validateToken(token)) { String username = jwtTokenUtil.getUsernameFromToken(token); // Set authentication context (e.g., Spring Security) ((HttpServletRequest) request).setAttribute("username", username); } } chain.doFilter(request, response); } @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void destroy() {} } |
Secure Your API Endpoints: With JWT authentication in place, you can secure your API endpoints by checking the Authorization
header and ensuring the token is valid.
Test JWT Authentication:
- Login Request: Send a POST request to the login endpoint with user credentials.
- JWT Response: If valid credentials, the server returns a JWT token.
- Subsequent Requests: Attach the JWT token in the
Authorization
header asBearer <token>
.