关于登录方式cookie,session,token
@Autowired RedisTemplate redisTemplate ; @Override public String login(LoginUser loginUser) { String cacheKey =UUID.randomUUID().toString(); redisTemplate.opsForValue().set(cacheKey ,loginUser.toString()); return cacheKey ; } public void testLogin(String cacheKey){ redisTemplate.opsForValue().get(cacheKey); }
通过Session
Session 代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的信息将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。也就是说,session 的作用是能够让服务器在某一用户登录之后,用户进行的所有操作都保持在同一会话之内,这样就能够记住用户的状态,并且能记住用户在这次会话中进行的一系列操作和保存的信息。
session 存储在服务器端,session 是用来存储信息的,在 cookie 里面插入的只是 session id,是识别某一 session 的唯一标识。
事实上,服务器在第一次获取 session 即调用 request.getSession() 的时候,服务器会创建一个 session 对象(session 是一个集合,并且是一个map集合),并且存入服务器的 session 集合中以 sessionId 为标识键,也就是说根据 sessionId 即可取到对应 session 的引用。同时也会创建一个键名为 JSESSIONID 的 cookie 并且返回给浏览器,该 cookie 的值即为 sessionId。
如果客户访问同一域的其他 Servlet,这个存储着 sessionId 的 cookie 就会跟着请求上传到服务器。此时如果请求的另一个Servlet也要使用 session,服务器会自动检查有没有这个保存 sessionId 的 cookie,如果有则直接到 session 集合中取对应的 session 引用返回给要使用的Servlet。所以说,在同一会话当中,不管请求哪个Servlet,拿到的都是同一个session。
我们这里所说的session都是基于cookie机制来实现的,所以可以说,session的实现是依赖于cookie的。
通过Session_id 追终, 客户端下次携带上JESSIONID的cookie来辨别 注意是自动携带的
public String loginBySession(HttpSession session,LoginUser loginUser){ session.setAttribute("user",loginUser);
session.getId(); return "success"; } public void testLoginBySession(HttpSession httpSession){ LoginUser loginUser = (LoginUser) httpSession.getAttribute("user"); }
通过Cookie的方式去登录
cookie存储在客户端,用到的时候直接携带上就可以
public String loginCookie(HttpServletRequest request){
Cookie[] cookies = request.getCookies();
String telephone=null;
for(Cookie cookie: cookies){
if("cook_telephone".equals(cookie.getName())){
telephone= cookie.getValue();
}
}
return telephone;
}
这些可能都不需要详细了解,需要详细了解JWT,参考
https://segmentfault.com/a/1190000012874052?utm_source=sf-similar-article
https://www.jianshu.com/p/e34a579c63a0

头部 head
声明类型声明加密算法:
//头部信息
eyJhbGciOiJIUzI1NiJ9 用在线网站解密后 {"alg":"HS256"}
eyJhbGciOiJub25lIn0 {"alg":"none"}
载荷 payload
载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分
- 标准中注册的声明
- 公共的声明
- 私有的声明
标准中注册的声明 (建议但不强制使用) :
- iss: jwt签发者
- sub: jwt所面向的用户
- aud: 接收jwt的一方
- exp: jwt的过期时间,这个过期时间必须要大于签发时间
- nbf: 定义在什么时间之前,该jwt都是不可用的.
- iat: jwt的签发时间
- jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.
私有的声明 :
私有声明是提供者和消费者所共同定义的,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息
String token = Jwts.builder().setSubject("暴富")
//payload
.claim("head_img", loginUser.getHeadImg())
.claim("id", loginUser.getId())
.claim("name", loginUser.getName())
.claim("mail", loginUser.getMail())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
// .signWith(SignatureAlgorithm.HS256, SECRET) // 这个盐加hash生成
.compact();
eyJzdWIiOiLmmrTlr4wiLCJpYXQiOjE2MzgzNjQ2OTYsImV4cCI6MTY0MDExNzcyOH0 解密: {"sub":"暴富","iat":1638364696,"exp":1640117728}
eyJzdWIiOiLmmrTlr4wiLCJpYXQiOjE2MzgzNjQ4OTMsImV4cCI6MTY0MDExNzkyNn0 解密: {"sub":"暴富","iat":1638364893,"exp":1640117926}
signature: 签证
jwt的第三部分是一个签证信息,这个签证信息由三部分组成:
- header (base64后的)
- payload (base64后的)
- secret
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。
pgyvlr_1uCDnPn-Iafb-xAumQKQ-AqLaWOnILiVk8b8 加了盐之后无法进行解析
public static Claims checkJWT(String token) { try { final Claims claims = Jwts.parser() .setSigningKey(SECRET)
//在头部加一个token信息,防止正对新破解 .parseClaimsJws(token.replace(TOKEN_PREFIX, "")).getBody(); return claims; } catch (Exception e) { log.info("jwt token解密失败"); return null; } }
使用到的包是
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
暂时写到这里,之后有更详细的解释

浙公网安备 33010602011771号