Java实现基于token认证
Java实现基于token认证
Jwt全称是:json web token,以JSON对象的形式安全的传递信息。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。
用户登录返回token进行验证的流程:
- 用户使用账号发出post请求;
- 服务器使用私钥创建一个token;
- 服务器返回这个token给浏览器;
- 浏览器将该token串在请求头中像服务器发送请求;
- 服务器验证该token;
- 返回响应的资源给浏览器。
优点
1.简洁: 可以通过URL、POST参数或者在HTTP header发送,因为数据量小,传输速度也很快;
2.自包含:负载中可以包含用户所需要的信息,避免了多次查询数据库;
3.因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持;
4.不需要在服务端保存会话信息,特别适用于分布式微服务(在符合规范时间内,服务器重启也可以继续使用)。
缺点
1.无法作废已颁布的令牌;
2.不易应对数据过期
简单介绍完看看:
Spring Boot和Jwt集成:
1.pom.xml依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
2.Token生成工具类
package com.cyb.springboot.utils;
import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;
/**
-
@author 车矣捕
-
@version 1.0
-
@description: 生成token
-
@date 2022/4/22 8:51
*/
public class TokenUtils {/**
- @description: 生成token
- @author 车矣捕
- @date: 2022/4/22
*/
public static String getToken(String userId,String sign){
return JWT.create().withAudience(userId) // 将 user id 保存到 token 里面 作为载荷
.withExpiresAt(DateUtil.offsetHour(new Date(),2)) //两小时后token过期
.sign(Algorithm.HMAC256(sign)); // 以 sign 作为 token 的密钥
}
}
3.登录请求生成并返回token
@Override
public UserDTO login(UserDTO userDTO) {
User one = getUserInfo(userDTO);
if (one!=null){
BeanUtil.copyProperties(one,userDTO,true);
//设置token
String token = TokenUtils.getToken(one.getId().toString(), one.getPassword());
userDTO.setToken(token);
return userDTO;
} else {
throw new ServiceException(Constants.CODE_600,"用户名或密码错误");
}
}
4.前端请求返回token
5.vue加入请求守卫(发送请求是token带上)
request.interceptors.request.use(config => {
let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null
if (user) {
config.headers['token'] = user.token; // 设置请求头
}
return config
});
6.发送请求带随token
7.创建 JwtInterceptor 实现拦截器 重写 preHandle 方法
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String token = request.getHeader("token");
// 如果不是映射到方法直接通过
if(!(handler instanceof HandlerMethod)) {
return true;
}
// 执行认证
if (StrUtil.isBlank(token)) {
throw new ServiceException(Constants.CODE_401,"无token,请重新登录");
}
// 获取 token 中的 user id
String userId;
try {
userId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new ServiceException(Constants.CODE_401,"token验证失败,请重新登录");
}
//根据token中的userid查询数据库*3. N/*
User user = userService.getById(userId);
if (user == null) {
throw new ServiceException(Constants.CODE_401,"用户不存在,请重新登录");
}
// 用户密码加签验证 token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token); //验证 token
} catch (JWTVerificationException e) {
throw new ServiceException(Constants.CODE_401,"token验证失败,请重新登录");
}
return true;
}
}
8.创建 InterceptorConfig 实现 WebMvcConfigurer,放行指定请求
/**
-
@author 车矣捕
-
@version 1.0
-
@description: 指定放行
-
@date 2022/4/22 9:54
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
.addPathPatterns(“/user”) // 拦截所有请求,通过判断 token是否合法 决定是否需要登录
.excludePathPatterns(“/user/**”,“/file/upload”);//需要放行的方法
// .excludePathPatterns(“/user/login”,“/user/register”,“/user/import”,“/user/export”);//需要放行的方法
}@Bean
public JwtInterceptor jwtInterceptor(){
return new JwtInterceptor();
}
}
更多推荐
所有评论(0)