使用 Spring Boot 实现 JWT 认证

概述

在现代的应用程序中,安全性是至关重要的。JWT(JSON Web Token)是一种用于在网络应用之间传递安全信息的开放标准。它由三部分组成,分别是头部(header)、载荷(payload)和签名(signature),通过对这三部分进行签名验证来保证数据的完整性和安全性。

在本文中,我将向你介绍如何使用 Spring Boot 实现 JWT 认证机制。

整体流程

下面是实现 Spring Boot JWT 认证的整体流程:

步骤 描述
1 用户使用用户名和密码进行登录请求
2 服务器验证用户的身份信息
3 服务器生成 JWT 并返回给客户端
4 客户端将 JWT 存储在本地
5 客户端每次请求时都携带 JWT
6 服务器验证 JWT 的合法性
7 服务器返回请求的数据

现在,让我们逐步说明每个步骤需要做什么。

步骤 1:用户登录请求

首先,用户需要向服务器发送一个登录请求,包含用户名和密码。这可以通过一个登录表单或者 API 请求来实现。

步骤 2:验证用户身份信息

服务器接收到登录请求后,需要验证用户的身份信息。这个过程可以涉及到查询数据库或者其他的验证机制。

步骤 3:生成 JWT

当服务器成功验证用户的身份信息后,需要生成一个 JWT 并将其返回给客户端。在生成 JWT 之前,需要引入相应的依赖。

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

然后,可以编写一个 JWT 工具类来生成 JWT。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtUtils {

    private static final String SECRET_KEY = "your-secret-key";
    private static final long EXPIRATION_TIME = 1000 * 60 * 60 * 24; // 1 day

    public static String generateJwt(String username) {
        Date now = new Date();
        Date expirationDate = new Date(now.getTime() + EXPIRATION_TIME);

        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    public static String getUsernameFromJwt(String jwt) {
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(jwt)
                .getBody();

        return claims.getSubject();
    }

    public static boolean validateJwt(String jwt) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(jwt);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

需要注意的是,SECRET_KEY 是用于生成和验证签名的密钥,可以根据实际情况替换为自己的密钥。

步骤 4:存储 JWT

客户端收到服务器返回的 JWT 后,需要将其存储在本地。可以使用浏览器的 LocalStorage 或者移动应用的 SharedPreferences 来实现。

步骤 5:请求时携带 JWT

客户端每次向服务器发送请求时,需要在请求头中携带 JWT。可以使用 Axios、HttpClient 等工具来发送请求。

import axios from 'axios';

const token = localStorage.getItem('jwt');

axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

axios.get('/api/data')
    .then(response => {
        // 处理响应数据
    })
    .catch(error => {
        // 处理错误
    });

步骤 6:验证 JWT 的合法性

服务器在收到请求时,需要验证 JWT 的合法性。可以编写一个拦截器或者过滤器来实现验证逻辑。

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtFilter implements Filter {

    private static