下面是详细讲解“Spring Boot集成JWT实现前后端认证的示例代码”的攻略。
什么是JWT
JWT全称为JSON Web Token。它是一种轻量级的身份验证机制,可以用于前后端之间的认证和授权。使用JWT进行认证,可以避免服务端为每个客户端的请求保存会话状态,从而提高服务的可伸缩性。
JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。头部包含了一些元数据,描述了令牌的类型和加密算法等;载荷包含了一些自定义的数据,比如用户的ID等;签名则显示了JWT的完整性,确保令牌没有被篡改。
JWT的优势
使用JWT进行认证比传统的cookie 或session认证具有一些优势:
-
无状态性:JWT在完成身份认证之后,不需要保存会话状态。客户端可以在每个请求中传递JWT,由服务端进行验证。因此,服务端的资源需要更少。
-
可扩展性:由于JWT是基于自包含的JSON结构,所以可以用于扩展其他数据。
-
安全性:JWT使用签名来验证令牌的完整性,防止令牌被篡改。此外,可以使用SSL/TLS来保护令牌。
现在我们开始来讲解如何在Spring Boot中集成JWT实现前后端认证。
步骤一:引入依赖
在pom.xml文件中加入以下依赖:
<!--JWT令牌实现-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
步骤二:添加JWT的配置类
在Spring Boot项目中添加JWT的配置类,其中包括:
-
生成JWT的方法
-
解析JWT的方法
-
配置JWT的一些参数
@Configuration
public class JwtConfig {
// 生成JWT的方法
public static String createToken(Map<String, Object> claims, String subject) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, "secret");
long expMillis = nowMillis + 120 * 60 * 1000; // 2小时有效期
Date exp = new Date(expMillis);
builder.setExpiration(exp);
return builder.compact();
}
// 解析JWT的方法
public static Claims parseToken(String token) {
try {
return Jwts.parser()
.setSigningKey("secret")
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
return null;
}
}
// 配置JWT参数
@Bean
public JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("secret");
return converter;
}
@Bean
public JwtTokenStore jwtTokenStore() {
return new JwtTokenStore(jwtAccessTokenConverter());
}
@Bean
public TokenEnhancer jwtTokenEnhancer() {
return new JwtTokenEnhancer();
}
// JWT token增加自定义属性
class JwtTokenEnhancer implements TokenEnhancer {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> info = new HashMap<>();
// 添加自定义属性,如用户ID等
info.put("user_id", 1);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
return accessToken;
}
}
}
步骤三:配置Spring Security
加入以下配置类配置Spring Security。其中包括了继承WebSecurityConfigurerAdapter的指定JWT的认证方式,还包括了继承AuthorizationServerConfigurerAdapter的认证授权方式。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
implements AuthorizationServerConfigurer {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenEnhancer jwtTokenEnhancer;
@Autowired
private JwtConfig jwtConfig;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.exceptionHandling()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.apply(new JwtConfigurer(jwtConfig, jwtTokenEnhancer));
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secret = "{noop}secret";
clients.inMemory()
.withClient("client")
.secret(secret)
.scopes("read", "write")
.authorizedGrantTypes("password", "refresh_token")
.accessTokenValiditySeconds(3600)
.refreshTokenValiditySeconds(7200)
.and()
.withClient("webapp")
.secret(secret)
.scopes("trust")
.authorizedGrantTypes("implicit")
.accessTokenValiditySeconds(3600);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(Arrays.asList(jwtTokenEnhancer, jwtConfig.jwtAccessTokenConverter()));
endpoints.authenticationManager(authenticationManager)
.tokenStore(jwtConfig.jwtTokenStore())
.tokenEnhancer(enhancerChain);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER");
}
}
示例一:生成JWT
下面是一个示例代码,用于在用户登录时生成一个JWT:
// 生成JWT
Map<String, Object> claims = new HashMap<>();
claims.put("sub", "user"); // 用户名等可定义的声明
String token = JwtConfig.createToken(claims, "user");
在这个示例中,生成JWT时传入了一个Map类型的claims,用于定义一些自定义的数据,比如用户名等。同时,在setExpiration中指定了JWT的过期时间为2小时。
示例二:解析JWT
下面是一个示例代码,用于在Spring Boot应用中解析JWT:
// 解析JWT
String token = "Bearer xxxx"; // 从Authorization头中提取出token
Claims claims = JwtConfig.parseToken(token);
if (claims != null) {
String username = claims.getSubject();
// todo: 验证用户凭据
} else {
// todo: token无效
}
在这个示例中,解析JWT时调用了JwtConfig类中的parseToken方法,传入了从Authorization头中提取出的token。在parseToken方法中,使用Jwts.parser()解析JWT,并使用setSigningKey("secret")方法指定了密钥为secret。如果解析成功,则可以获得一些自定义的数据,比如用户名等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot 集成JWT实现前后端认证的示例代码 - Python技术站