3.3.11 测试登录认证接口
3.4 认证成功返回token
3.4.3 认证成功处理器返回token信息
```package com.manong.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginResult {
//用户编号
private Long id;
//状态码
private int code;
//token令牌
private String token;
//token过期时间
private Long expireTime;
}
编写token工具类:
```@Data
@ConfigurationProperties(prefix = "jwt")
@Component
public class JwtUtils {
//密钥
private String secret;
// 过期时间 毫秒
private Long expiration;
/**
* 从数据声明生成令牌
*
* @param claims 数据声明
* @return 令牌
*/
private String generateToken(Map<String, Object> claims) {
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
return
Jwts.builder().setClaims(claims).setExpiration(expirationDate).signWith(Signatur
eAlgorithm.HS512, secret).compact();
}
/**
* 从令牌中获取数据声明
*
* @param token 令牌
* @return 数据声明
*/
public Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims =
Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
/**
* 生成令牌
*
* @param userDetails 用户
* @return 令牌
*/
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>(2);
claims.put(Claims.SUBJECT, userDetails.getUsername());
claims.put(Claims.ISSUED_AT, new Date());
return generateToken(claims);
}
/**
* 从令牌中获取用户名
*
* @param token 令牌
* @return 用户名
*/
public String getUsernameFromToken(String token) {
String username;
try {
Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
/**
* 判断令牌是否过期
*
* @param token 令牌
* @return 是否过期
*/
public Boolean isTokenExpired(String token) {
Claims claims = getClaimsFromToken(token);
Date expiration = claims.getExpiration();
return expiration.before(new Date());
}
/**
* 刷新令牌
*
* @param token 原令牌
* @return 新令牌
*/
public String refreshToken(String token) {
String refreshedToken;
try {
Claims claims = getClaimsFromToken(token);
claims.put(Claims.ISSUED_AT, new Date());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
/**
* 验证令牌
*
* @param token 令牌
* @param userDetails 用户
* @return 是否有效
*/
public Boolean validateToken(String token, UserDetails userDetails) {
User user = (User) userDetails;
String username = getUsernameFromToken(token);
return (username.equals(user.getUsername()) && !isTokenExpired(token));
}
}
(3)编写全局配置文件
在application.properties全局配置文件中自定义jwt属性。
#密钥
jwt.secret=com.manong
#过期时间
jwt.expiration=1800000
(4)认证成功处理器类返回token数据 在原有的LoginSuccessHandler登录认证成功处理器类上加入jwt相关代码。 注意:在原有的基础上添加
* 登录认证成功处理器类
*/
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
@Resource
private JwtUtils jwtUtils;
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) throws IOException,
ServletException {
//设置客户端的响应的内容类型
response.setContentType("application/json;charset=UTF-8");
//获取当登录用户信息
User user = (User) authentication.getPrincipal();
//生成token
String token = jwtUtils.generateToken(user);
//设置token签名密钥及过期时间
long expireTime = Jwts.parser() //获取DefaultJwtParser对象
.setSigningKey(jwtUtils.getSecret()) //设置签名的密钥
.parseClaimsJws(token.replace("jwt_", ""))
.getBody().getExpiration().getTime();//获取token过期时间
//创建登录结果对象
LoginResult loginResult = new LoginResult(user.getId(),
ResultCode.SUCCESS,token,expireTime);
//消除循环引用
String result = JSON.toJSONString(loginResult,
SerializerFeature.DisableCircularReferenceDetect);
//获取输出流
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(result.getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
}
}
3.6 token验证
3.6.1 添加Redis依赖
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>