Java JWT 如何通过验证

在现代应用程序中,安全性是一个至关重要的方面。JSON Web Token(JWT)是用于身份验证和信息交换的常见方法。在这篇文章中,我们将探讨如何使用 Java 和 JWT 来验证用户身份,并提供实际的代码示例和序列图说明其过程。

JWT 的基本概念

JWT 是一种用于安全传输信息的紧凑URL安全的令牌。JWT 由三部分组成:

  1. 头部 (Header):通常包含令牌类型(JWT)和签名算法(如 HMAC SHA256)。
  2. 负载 (Payload):包含需要传递的数据,比如用户的身份信息和其他元数据。
  3. 签名 (Signature):通过头部和负载以及密钥生成的签名,确保数据的完整性。

使用 Java 实现 JWT 验证

依赖配置

首先,我们需要在 Maven 项目中添加 JWT 的依赖项。在 pom.xml 中添加以下内容:

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

生成 JWT

我们首先编写一个生成 JWT 的方法:

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

import java.util.Date;

public class JwtUtil {
    private static final String SECRET_KEY = "your_secret_key";

    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + 600000)) // 10分钟有效期
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }
}

验证 JWT

接下来,我们需要实现一个方法来验证 JWT。该方法将解析 token,并检查其有效性和签名。

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;

public class JwtUtil {
    // 前面的 generateToken 方法保持不变

    public static Claims validateToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (SignatureException e) {
            throw new RuntimeException("Invalid JWT signature");
        } catch (Exception e) {
            throw new RuntimeException("Token expired or invalid");
        }
    }
}

使用示例

现在我们可以使用这些方法在应用程序中生成和验证 JWT。以下是一个示例控制器:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AuthController {

    @GetMapping("/login")
    public String login(String username) {
        // 这里通常会进行用户验证
        return JwtUtil.generateToken(username);
    }

    @GetMapping("/protected")
    public String protectedResource(@RequestHeader("Authorization") String token) {
        String username;
        try {
            Claims claims = JwtUtil.validateToken(token.replace("Bearer ", ""));
            username = claims.getSubject();
        } catch (RuntimeException e) {
            return e.getMessage();
        }
        return "Hello " + username + ", you have access to this protected resource!";
    }
}

序列图

以下是 JWT 生成和验证过程的序列图:

sequenceDiagram
    participant User
    participant AuthController
    participant JwtUtil

    User->>AuthController: 请求登录(username)
    AuthController->>JwtUtil: 生成Token(username)
    JwtUtil-->>AuthController: 返回Token
    AuthController-->>User: 返回Token

    User->>AuthController: 访问受保护资源(Token)
    AuthController->>JwtUtil: 验证Token
    JwtUtil-->>AuthController: 返回Claims(username)
    AuthController-->>User: 返回受保护资源

结论

本文展示了如何使用 Java 和 JWT 来处理用户身份验证的基本方案。通过简单的方法组合,我们可以生成和验证 JWT,确保应用程序的安全。JWT 的使用可以提高用户体验,并通过无状态的方式支持扩展。如果您的应用程序需要安全有效的身份验证方案,JWT 将是一个非常明智的选择。