1月26日java假期学习读书笔记

一、学习目标
了解JWT(JSON Web Token)的基本概念和优势。
掌握如何在Spring Boot应用中集成JWT实现无状态认证。
学习JWT的生成和验证机制。
通过实际练习,实现一个基于JWT的用户认证系统。
理解JWT在分布式系统中的应用场景。
二、学习内容
(一)JWT(JSON Web Token)简介
什么是JWT?
JWT是一种开放标准(RFC 7519),用于在各方之间以JSON对象安全地传递信息。
JWT的信息可以被验证和信任,因为它是数字签名的。
JWT的结构
Header(头部):通常包含令牌的类型(如JWT)和所使用的签名算法。
Payload(载荷):包含声明(Claims),如用户信息、过期时间等。
Signature(签名):用于验证消息的完整性和真实性。
JWT的优势
无状态:JWT包含所有必要的信息,服务器无需存储用户状态。
可扩展:JWT可以携带用户信息,减少数据库查询。
跨域支持:JWT可以用于跨域认证。
(二)在Spring Boot中集成JWT
添加依赖
在pom.xml中添加JWT相关依赖(如java-jwt或JJWT):
xml
复制

io.jsonwebtoken
jjwt
0.9.1

生成JWT
示例代码:
java
复制
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

public class JwtUtil {
private static final String SECRET_KEY = "yourSecretKey"; // 密钥

public static String generateToken(String username) {
    long nowMillis = System.currentTimeMillis();
    Date now = new Date(nowMillis);
    long expMillis = nowMillis + 3600000; // 令牌有效期为1小时
    Date exp = new Date(expMillis);

    return Jwts.builder()
               .setSubject(username) // 设置主题(通常是用户名)
               .setIssuedAt(now) // 设置签发时间
               .setExpiration(exp) // 设置过期时间
               .signWith(SignatureAlgorithm.HS512, SECRET_KEY) // 设置签名算法和密钥
               .compact(); // 构建JWT并将其序列化为一个紧凑、URL安全的字符串
}

}
验证JWT
示例代码:
java
复制
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

public class JwtUtil {
private static final String SECRET_KEY = "yourSecretKey"; // 密钥

public static Claims parseToken(String token) {
    return Jwts.parser()
               .setSigningKey(SECRET_KEY) // 设置签名密钥
               .parseClaimsJws(token) // 解析JWT
               .getBody(); // 获取载荷
}

}
(三)Spring Security集成JWT
配置JWT过滤器
创建一个过滤器用于解析和验证JWT:
java
复制
@Component
public class JwtRequestFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws ServletException, IOException {

    final String authorizationHeader = request.getHeader("Authorization");

    String username = null;
    String jwt = null;

    if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
        jwt = authorizationHeader.substring(7);
        username = JwtUtil.parseToken(jwt).getSubject();
    }

    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
        if (username.equals("admin")) { // 简单验证
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                    username, null, new ArrayList<>());
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        }
    }
    chain.doFilter(request, response);
}

}
配置Spring Security
在SecurityConfig中添加JWT过滤器:
java
复制
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private JwtRequestFilter jwtRequestFilter;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers("/authenticate").permitAll() // 允许访问登录接口
        .anyRequest().authenticated()
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // 无状态

    http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

}
(四)实际练习:实现基于JWT的用户认证
创建用户认证接口
java
复制
@RestController
public class AuthenticationController {

@PostMapping("/authenticate")
public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthenticationRequest request) {
    // 简单验证用户名和密码
    if ("admin".equals(request.getUsername()) && "admin".equals(request.getPassword())) {
        String token = JwtUtil.generateToken(request.getUsername());
        return ResponseEntity.ok(new AuthenticationResponse(token));
    } else {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
    }
}

}

class AuthenticationRequest {
private String username;
private String password;

// Getters and Setters

}

class AuthenticationResponse {
private String token;

public AuthenticationResponse(String token) {
    this.token = token;
}

// Getters and Setters

}
运行和测试
启动项目后,使用Postman测试登录接口:
bash
复制
curl -X POST http://localhost:8080/authenticate -H "Content-Type: application/json" -d '{"username":"admin","password":"admin"}'
返回JWT:
JSON
复制
{
"token": "eyJhbGciOiJIUzUxMiJ9..."
}
使用JWT访问受保护的接口:
bash
复制
curl -X GET http://localhost:8080/user/info -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9..."
三、学习心得
JWT的优势
JWT是无状态的,服务器无需存储用户状态,适合分布式系统。
JWT可以携带用户信息,减少数据库查询,提高性能。
Spring Security与JWT的结合
Spring Security提供了强大的安全框架,结合JWT可以实现灵活的无状态认证。
通过自定义过滤器,可以轻松集成JWT到Spring Security中。
实践的重要性
通过实际编写代码,我更好地理解了JWT的生成和验证机制。
实践可以帮助快速发现和解决问题,加深对知识点的理解。

posted @ 2025-02-19 23:42  头发少的文不识  阅读(37)  评论(0)    收藏  举报