1.什么是Jwt
JWT (全称:Json Web Token)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为 JSON 对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
1.1前端访问后端流程
- 用户使用账号、密码登录应用,登录的请求发送到 Authentication Server。
- Authentication Server 进行用户验证,然后创建 JWT 字符串返回给客户端。
- 客户端请求接口时,在请求头带上 JWT。
- Application Server 验证 JWT 合法性,如果合法则继续调用应用接口返回结果。
1.2JWT结构
JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE1ODc1NDgyMTV9.BCwUy3jnUQ_E6TqCayc7rCHkx-vxxdagUwPOWqwYCFc
1.3Jwt的优点
- json格式的通用性,所以JWT可以跨语言支持,比如Java、JavaScript、PHP、Node等等。
- 可以利用Payload存储一些非敏感的信息。
- 便于传输,JWT结构简单,字节占用小。
- 不需要在服务端保存会话信息,易于应用的扩展。
2.添加pom依赖
<!-- JWT-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.2</version>
</dependency>
3.新建JwtUtils工具类
public class JwtUtils {
//自定义加密密钥
private static final String sign="@%dpf**";
public static String createToken(String userId){
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE,10);// 设置一个十分钟的时间段
return JWT.create().withAudience(userId) //将user id 保存到token里面,作为载荷
.withExpiresAt(calendar.getTime()) // 设置十分钟过期
.sign(Algorithm.HMAC256(sign));//添加token秘钥
}
/**
* 验证token合法性
*/
public static DecodedJWT verify(String token){
DecodedJWT decodedJWT=null;
try{
//return JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
// 使用JWT的require,生成一个验证对象
decodedJWT=JWT.require(Algorithm.HMAC256(sign)).build().verify(token);
return decodedJWT;
}catch (Exception e){
//抛出异常赋为null
decodedJWT=null;
return decodedJWT;
}
}
}
注意:密钥sing可自行设置
4.添加拦截认证类
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");//从请求头获得token
//如果不是映射到方法直接通过
if (!(handler instanceof HandlerMethod)) {
return true;
}
if(token == null) return false;
//执行认证
if ("".equals(token)) {
System.out.println("无token,请重新认证");
return false;
}
//用户密码加签验证 token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("@%dpf**")).build();
try {
jwtVerifier.verify(token); //验证token
} catch (JWTVerificationException e) {
System.out.println("验证失败");
retuen false;
}
return true;
}
}
注意String token = request.getHeader("token");//从请求头获得token 要求前端访问时将jwt保存到请求头中。
5.设置拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/**") //全部拦截
.excludePathPatterns("/user/login", "/student/getName", "/**/export", "/**/import", "/file/**");//此处设置不需要拦截的后端访问路径,可根据需要自行设置
}
@Bean
public JwtInterceptor jwtInterceptor() {
return new JwtInterceptor();
}
}
可根据需要自行设置拦截和放行的路径。
注意登录时前端需要将jwt保存,每次访问后端接口时都需要在请求头中带上jwt字符串(即token)。