- 生成解析的JWT中的secretKey不应该定义在2个类中
- 解析JWT时出现的异常,未处理
- 认证信息中不包含id
- 认证信息中的权限还没有数据
- 还未结合前端
使用配置类文件自定义JWT参数
生成和解析的JWT都需要使用secretKey,并且生成和解析的值完全相同。所以需要选择一个公共的位置来配置secretKey值。由于这个值是允许被软件的使用者进行修改,因此应该将值定义在配置文件中。则可以在application.properties或者application.yml文件中
#当前项目中的自定义配置
project:
#JWT相关配置
jwt:
#生成和解析JWT时使用的secretKey
secret-key: as3fsfds3sf3sdf56sdf
#JWT的有效时长,以分钟为单位
duration-in-minute: 600
在.properties或.yml中添加配置之后,在加载时。会将这些配置读取到Spring框架内置的Enviroment对象中。操作系统的配置和JVM的配置也会自动读取到Enviroment中。配置文件中的配置优先级时最低的(会被覆盖),使用@Value读取值,这个值是从Environmet中读取的,而不是配置文件。
添加配置后,在生成和解析JWT时使用,即在两个类(登录管理员和过滤器)的全局属性中,通过@Value注解为这2个属性注入配置值
@Value("${project.jwt.secert-key}")
private String secretKey;
@Value("${project.jwt.duration-in-minute}")
private Long durationInMinute;
处理解析JWT时出现的异常
当前是使用过滤器解析JWT,而过滤器是Java EE项目中最早接收到请求的组件,此时其他组件均为开始处理此请求。所以,如果在过滤器请求中出现异常,Controller无法知晓,则全局异常处理器也无法处理异常,只能在过滤器中使用try...catch处理。
处理异常需要响应JSON格式,但是,由于过滤器解析JWT时,Spring MVC的相关组件还没运行,无法转化成JSON格式的字符串。需要在项目中添加依赖项,用于将对象转换成JSON格式的字符串。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
然后在服务代码添加新的枚举,用于返回错误的代码
public enum ServiceCode{
/**
错误:JWT签名错误
*/
ERR_JWT_SIGNATURE(6000),
/**
错误:JWT数据格式错误
*/
ERR_JWT_MALFORMED(6100),
/**
错误:JWT已过期
*/
ERR_JWT_EXPIRED(6200),
}
最后在过滤器的类中,使用try...catch包裹解析JWT的代码,并处理相关异常
try {
claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(jwt)
.getBody();
} catch (SignatureException e) {
log.debug("解析JWT时出现SignatureException");
String message = "非法访问!";
JsonResult<Void> jsonResult = JsonResult.fail(
ServiceCode.ERR_JWT_SIGNATURE, message);
String jsonResultString = JSON.toJSONString(jsonResult);