SpringBoot集成JWT实现token验证 | 苍穹帝-CSDN
<!-- jwt -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
@Component
public class TokenUtils {
private static final long EXPIRE_TIME = 60 * 60 * 1000; //过期时间1小时
@Autowired
public static UserService staticUserService;
@Autowired
public UserService userService;
@PostConstruct
public void setUserService() {
staticUserService = userService;
}
//生成token
public static String getToken(String userId, String sign) {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
String token = "";
token = JWT.create().withAudience(userId) // 将 userId 保存到 token 里面
.withExpiresAt(date) //1小时后token过期
.sign(Algorithm.HMAC256(sign)); // 以 password 作为 token 的密钥
return token;
}
//获取当前登录的用户信息
public static User getCurrentUser() {
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String token = request.getHeader("token");
if (!StringUtils.isEmpty(token)) {
String userId = JWT.decode(token).getAudience().get(0);
return staticUserService.getById(Integer.valueOf(userId));
}
} catch (Exception e) {
return null;
}
return null;
}
}
//token拦截器
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) {
String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
// 如果不是映射到方法直接通过
if (!(object instanceof HandlerMethod)) {
return true;
}
// 执行认证
if (StringUtils.isEmpty(token)) {
throw new MyException(ResultCodeEnum.TOKEN_ERROR);
}
// 获取token中的userId
String userId;
try {
userId = JWT.decode(token).getAudience().get(0);
} catch (JWTDecodeException j) {
throw new MyException(ResultCodeEnum.TOKEN_CHECK_ERROR);
}
// 根据token中的userId查询数据库
User user = userService.getById(userId);
if (user == null) {
throw new MyException(ResultCodeEnum.USER_NOT_EXISTS);
}
// 用户密码加签验证 token
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
try {
jwtVerifier.verify(token);
} catch (JWTVerificationException e) {
throw new MyException(ResultCodeEnum.TOKEN_CHECK_ERROR);
}
return true;
}
}
//拦截器配置
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor())
.addPathPatterns("/**")// 拦截所有请求,通过判断是否有token注解决定是否需要登录
.excludePathPatterns(//添加不拦截路径
"/user/login", //登录
"/user/register" //注册
);
}
@Bean
public JwtInterceptor jwtInterceptor() {
return new JwtInterceptor();
}
}
//全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Result error(Exception e) {
e.printStackTrace();
return Result.fail();
}
//自定义异常处理方法
@ExceptionHandler(MyException.class)
@ResponseBody
public Result error(MyException e) {
return Result.build(e.getCode(), e.getMessage());
}
}
//自定义全局异常类
@Data
public class MyException extends RuntimeException {
private Integer code;
//通过状态码和错误消息创建异常对象
public MyException(String message, Integer code) {
super(message);
this.code = code;
}
//接收枚举类型对象
public MyException(ResultCodeEnum resultCodeEnum) {
super(resultCodeEnum.getMessage());
this.code = resultCodeEnum.getCode();
}
@Override
public String toString() {
return "YyghException{" +
"code=" + code +
", message=" + this.getMessage() +
'}';
}
}
//统一返回结果状态信息类
@Getter
public enum ResultCodeEnum {
TOKEN_ERROR(400, "无token,请重新登录"),
TOKEN_CHECK_ERROR(401,"token验证失败,请重新登录"),
USER_NOT_EXISTS(402,"用户不存在,请重新登录"),
;
private Integer code;
private String message;
private ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}
@Override
public UserVo login(UserVo userVo) {
User one = getUserInfo(userVo);
if (one != null) {
BeanUtils.copyProperties(one, userVo);
// 设置token
String token = TokenUtils.getToken(one.getId().toString(), one.getPassword());
userVo.setToken(token);
return userVo;
} else {
throw new MyException(ResultCodeEnum.LOGIN_ERROR);
}
}
import axios from 'axios'
import ElementUI from 'element-ui';
import {serverIp} from "../../public/config";
import router from "@/router";
const request = axios.create({
baseURL: `http://${serverIp}/`,
timeout: 5000
})
//request 拦截器
//可以自请求发送前对请求做一些处理
//比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
config.headers['Content-Type'] = 'application/json;charset=utf-8';
let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null
if (user) {
config.headers['token'] = user.token; // 设置请求头
}
return config
}, error => {
return Promise.reject(error)
});
//response 拦截器
//可以在接口响应后统一处理结果
request.interceptors.response.use(
response => {
let res = response.data;
//如果是返回的文件
if (response.config.responseType === 'blob') {
return res
}
//兼容服务端返回的字符串数据
if (typeof res === 'string') {
res = res ? JSON.parse(res) : res
}
// 当权限验证不通过的时候给出提示
if (res.code >= 400 && res.code < 500) {
ElementUI.Message({
message: res.message,
type: 'error'
});
router.push("/login")
}
return res;
},
error => {
console.log('err' + error) // for debug
return Promise.reject(error)
}
)
export default request