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
复制
生成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的生成和验证机制。
实践可以帮助快速发现和解决问题,加深对知识点的理解。
浙公网安备 33010602011771号