session的缺点
- session存于服务器上,当并发高的时候,服务器压力大
- 当扩展服务器集群的时候,session因为只存于一个服务器上,就不好用了
- session结合cookie,容易被攻击
实现原理
[不知道对不对]
- 前端传来用户名密码(例如name、password)
- 后端接收生成对象(user)
- 生成uuid作为token令牌(就是一个唯一的字符串str)
- 将token作为key,user作为valued存到redis
- 将token返回给前端
- 前端将token保存
- 请求的时候将token放到header里面
- 后端再次接收请求的时候从header里面获取token,从redis验证取出对象进行操作
java实现
实体类user,因为要存到redis就要序列化,所以要对user做可序列化操作
package com.example.demo.entity;
import java.io.Serializable;
public class User implements Serializable {
private String name;
private String password;
private static final long serialVersionUID = 1L;
……
}
需要用到redis,springboot集成redis看其他文章
controller
@Controller
public class TokenController {
@Resource
private RedisTemplate<Object,Object> redisTemplate;
//登陆生成token并返回
@GetMapping("/tokenin")
@ResponseBody
public Object getToken(User user){
String token= UUID.randomUUID()+"";
//以令牌为key,user为value存储30分钟(参数是long类型的)
redisTemplate.opsForValue().set(token,user, Duration.ofMinutes(30L));
return token;
}
//访问需要token的信息
@GetMapping("/tokened")
@ResponseBody
public Object tokened(HttpServletRequest rq){
//获取header里的参数
String token= rq.getHeader("token");
//查询redis中剩余失效时间
Long expire=redisTemplate.getExpire(token);
User user=null;
if(expire>0){
user=(User) redisTemplate.opsForValue().get(token);
//设置redis失效时间
redisTemplate.expire(token,Duration.ofMinutes(30L));
//删除redis数据
redisTemplate.delete(token);
}
return user;
}
}