【keel】4. 实现jwt登录

1. JWT 的基本概念

JWT 是一种用于在网络应用环境中安全地传递信息的紧凑的 URL 安全的令牌。它可以被验证和信任,因为它是数字签名的。JWT 通常用于身份验证和信息交换。

这里详细说一下原理,一般有两种形式

  • 对称加密:简单速度快,但是风险较高
  • 非对称加密:原理复杂,速度慢,但是安全度高

这里说说非对称加密的方式,其实和https类似是一个“藏钥匙”的机制,私钥(sk)保留在服务器中不参与外部服务和模块的迁移,保证安全性,sk加密的签名A和头部、载荷一起发送到客户端,当客户端伪造了权限(一般是载荷中的信息),服务器拿到jwt后根据载荷和头部依据相同算法计算出一个hash(hp),然后用公钥解码签名拿到另一个hash(sp)如果sp和hp一致那么就是没有篡改,因为篡改了载荷的话hash值也就是摘要会变化原理就是这么简单。

2. 依赖项

在 pom.xml 文件中,项目使用了以下依赖项来处理 JWT:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
</dependency>

3. JWT 生成

在 JwtUtil 类中,JWT 的生成通过以下方法实现:generateToken 方法: 接收用户名并创建一个包含用户信息的 JWT。createToken 方法: 使用 Jwts.builder() 构建 JWT,设置声明、主题、签发时间和过期时间,并使用安全密钥进行签名。

public String generateToken(String username) {
    Map<String, Object> claims = new HashMap<>();
    return createToken(claims, username);
}

private String createToken(Map<String, Object> claims, String subject) {
    return Jwts.builder()
            .setClaims(claims)
            .setSubject(subject)
            .setIssuedAt(new Date(System.currentTimeMillis()))
            .setExpiration(new Date(System.currentTimeMillis() + validityInMilliseconds))
            .signWith(secretKey) // 使用生成的安全密钥
            .compact();
}

4. JWT 验证

在 ProtectedController 类中,JWT 的验证通过以下步骤实现:提取用户名: 使用 jwtUtil.extractUsername(token) 从 JWT 中提取用户名。验证令牌: 使用 jwtUtil.validateToken(token, username) 验证 JWT 的有效性。

@GetMapping("/protected")
public String protectedEndpoint(@RequestHeader("Authorization") String token) {
    String username = jwtUtil.extractUsername(token);
    if (jwtUtil.validateToken(token, username)) {
        return "This is a protected endpoint. Hello, " + username + "!";
    } else {
        throw new RuntimeException("Invalid token");
    }
}

5. 安全配置

在 SecurityConfig 类中,配置了 Spring Security,以允许某些端点(如 /authenticate 和 /hello)不需要身份验证,而其他请求则需要身份验证。

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        .requestMatchers("/authenticate").permitAll()
        .requestMatchers("/hello").permitAll()
        .anyRequest().authenticated();
    return http.build();
}

6. 用户认证

在 AuthController 类中,处理用户认证请求。使用硬编码的用户名和密码进行验证,并在成功时生成 JWT。

@PostMapping("/authenticate")
public Map<String, String> authenticate(@RequestBody AuthRequest authRequest) {
    if ("user".equals(authRequest.getUsername()) && "password".equals(authRequest.getPassword())) {
        String token = jwtUtil.generateToken(authRequest.getUsername());
        return Collections.singletonMap("token", token);
    } else {
        throw new RuntimeException("Invalid credentials");
    }
}

7. 密钥管理

在 JwtUtil 类中,使用 Keys.secretKeyFor(SignatureAlgorithm.HS256) 方法生成一个安全的密钥,以确保密钥的大小符合 HS256 的要求(至少 256 位)。

总结

JWT 是一种安全的身份验证机制,适用于现代 Web 应用程序。通过使用 jjwt 库,项目能够有效地生成和验证 JWT,确保用户的身份安全。通过适当的安全配置,应用程序能够控制对受保护资源的访问。如果你有任何其他问题或需要进一步的细节,请告诉我!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部