我这种token只是简单的实现token,就是后端利用UUID 生成简单随机码,利用随机码作为在Redis中的键,然后存储的用户信息作为值,在每次合理请求的时候对token的有效时间进行刷新(利用拦截器),以确保用户信息的有效性。
使用令牌(Token)进行身份验证和授权是一种常见的方式,特别适用于分布式和跨域请求的应用程序。
1. 为什么要使用 Token:
2. Token 使用逻辑:
@GetMapping("/login")
public BaseResponse<String> login(String username,String password){
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getUsername,username);
User one = userService.getOne(lambdaQueryWrapper);
if(one == null){
throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
}
String token = UUID.randomUUID().toString();
redisTemplate.opsForHash().putAll("test:user:"+token, BeanUtil.beanToMap(one));
redisTemplate.expire("test:user:" + token,2, TimeUnit.MINUTES);
return ResultUtils.success(token);
}
@GetMapping("/get")
public BaseResponse<User> get(){
return ResultUtils.success(UserHolder.getValue());
}
public class LoginInterceptor implements HandlerInterceptor {
private RedisTemplate<String,Object> redisTemplate;
public LoginInterceptor(RedisTemplate<String,Object> template){
this.redisTemplate = template;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 获取 session
String token = request.getHeader("Authorization");
// 检查用户是否已登录
User user = new User();
BeanUtil.fillBeanWithMap(redisTemplate.opsForHash().entries("test:user:"+token),user,false);
if(user == null|| BeanUtil.isEmpty(user)){
throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
}
redisTemplate.expire("test:user:"+token,2, TimeUnit.MINUTES);
// 将用户数据存储到 ThreadLocal 中,以便在整个请求周期内访问
UserHolder.setValue(user);
// 进行其他逻辑验证,根据需求自行添加
return true; // 允许请求继续执行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 在请求处理之后执行,可以对 ModelAndView 进行修改
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 在请求完成之后执行,用于资源清理等操作
// 清理 ThreadLocal 中的用户数据,防止内存泄漏
UserHolder.clear();
}
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Resource
private RedisTemplate<String,Object> redisTemplate;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 登录拦截器
registry.addInterceptor(new LoginInterceptor(redisTemplate))
.addPathPatterns("/**").excludePathPatterns("/user/login");
}
}
结果返回了一个token,这个token前端拿到以后要保存到sessionStorage或者LocalStorage里面,再把这个token送到请求头中,就可以啦

设置请求头
设置Authorization

然后发起就可以得到啦

如果没有authorization就是得到未登录结果

前端(Vue.js)示例: