在现代微服务架构中,JWT(JSON Web Token)因其自包含的特性而越来越受到欢迎。它可以用于实现安全的身份验证和授权。本文将介绍如何在Spring Boot项目中,基于JWT实现单token授权与续期方案。
JWT的基本概念
JWT由三部分组成:头部(Header)、有效载荷(Payload)和签名(Signature)。头部通常包含令牌类型(JWT)和所使用的加密算法。有效载荷包含用户信息和其他元数据,签名则用于验证消息的完整性。
一、依赖配置
在你的Spring Boot项目中,首先需要添加相关依赖。你可以在pom.xml
中添加以下依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
二、JWT工具类
我们需要一个工具类来生成和解析JWT:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtUtil {
private static final String SECRET_KEY = "your_secret_key"; // 请使用更复杂的密钥
private static final long EXPIRATION_TIME = 604800000L; // 一周的毫秒数
public static String createToken(String username) {
Map<String, Object> claims = new HashMap<>();
claims.put("username", username);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
public static Claims parseToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
}
三、Spring Security配置
接下来,我们需要在Spring Security中配置JWT的相关处理:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 配置用户认证方式
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()));
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
四、授权与续期
接下来,我们可以实现JWT的授权和续期功能。创建一个控制器处理登录请求和续期请求:
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/auth")
public class AuthController {
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
// 检查用户名和密码的代码(省略)
// 生成并返回JWT Token
return JwtUtil.createToken(username);
}
@PostMapping("/refresh")
public String refresh(@RequestHeader("Authorization") String token) {
// 解析JWT
Claims claims = JwtUtil.parseToken(token.replace("Bearer ", ""));
// 生成新的Token
return JwtUtil.createToken(claims.get("username").toString());
}
}
总结
通过以上步骤,我们实现了一个基于JWT的单Token授权方案,并提供了Token的续期功能。在实际应用中,建议将JWT的有效期设置得足够长,以减少频繁登录的需求,同时注意安全性,采用合适的策略存储和验证密钥。这样可以确保用户的会话安全,改善用户体验。