zl程序教程

您现在的位置是:首页 > 

当前栏目

Session到Token认识和理解

理解 session 认识 Token
2023-06-13 09:11:25 时间

客户端记录用户登录网站的信息,确定用户身份。它是一小段文本信息,这个文本信息最早由W3C提出,现在的主流浏览器都支持这种机制。(谷歌浏览器是最为标准的遵照W3C规范的浏览器)

每次登录一个网站的时候,相当于我们的浏览器是客户端,向服务端发送各种请求。但是如果我们想买一个东西,俩个用户分别将商品加入购物车。通过HTTP协议完成,服务器获得了俩个用户的请求,这个请求完成相当于数据交换完毕,自然这个连接就会关闭。当其中一个用户准备结账的时候又要重新建立连接,但是服务器不知道是哪一个用户的购物车商品。这就出现了无法跟踪的状况。

因为实际需要保持这种状态,就提供了这种机制。由服务器产生内容,浏览器收到后保存到本地,下一次再进行连接时,就会带着服务器给的信息跟踪到这个位置,它的容量不超过4M。

Session

从上面可以看出Cookie的机制意味着可能在本地被恶意劫持,所以就需要引入具有同样机理的Session,只是Session保存在服务器端,相当于每建立一次连接就建立了这样的会话,而会话的信息也是不超过4M的文本字典数据。Session有一个特点是具有时限性,一般只能保存一段时间,比如你关闭浏览器,再打开你的某个网站的登录信息还在。但是你关闭浏览器半小时再打开就需要重新登录了。

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
        req.setCharacterEncoding("UTF-8"); 
        resp.setCharacterEncoding("UTF-8"); 
        resp.setContentType("text/html;charset=utf-8"); 
 PrintWriter out = resp.getWriter(); 
 Cookie[] cookies = req.getCookies();//请求获得Cookie可能不止一个 
 //判断Cookie是否为空 
 if(cookies!=null){ 
            out.write("Your last visit  time is:"); 
 for(Cookie cookie:cookies){ 
 if( cookie.getName().equals("lastLoginTime")){ 
 long lastLoginTime = Long.parseLong(cookie.getValue()); 
 Date date = new Date(lastLoginTime); 
 //解码 
                    out.write(URLDecoder.decode( date.toLocaleString(),"UTF-8")); 
 } 
 } 
 }else { 
            out.write("This is your first visit to this site:"); 
 } 
 //编码 
 Cookie cookie = new Cookie("lastLoginTime", URLEncoder.encode(System.currentTimeMillis()+"","UTF-8")); 
 //设置Cookie的有效期(有效期不能为0) 
        cookie.setMaxAge(24*60*60); 
 //服务端给客户端发送Cookie 
        resp.addCookie(cookie); 
 } 

这个类可以在每一次请求的时候响应一个Cookie。

Session在创建的时候都会创建一个名为JSESSIONID的cookie。

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
 //解决乱码问题 
        req.setCharacterEncoding("UTF-8"); 
        resp.setCharacterEncoding("UTF-8"); 
        resp.setContentType("text/html;charset=utf-8"); 
 //获得Session 
 HttpSession session = req.getSession(); 
 //session中存放用户信息 
        session.setAttribute("name","wangwei"); 
 //获得Session ID 
 String sessionId = session.getId(); 
 //判断session是否为新创建的 
 if(session.isNew()){ 
            resp.getWriter().write("Seesion创建成功,ID:"+sessionId); 
 }else{ 
            resp.getWriter().write("服务器中已经存在的当前请求的Seession,ID:"+sessionId); 
 } 
 } 

也可以获取session的内容和移除session的内容,具体就彩印对应的get和remove方法。

HttpSession session = req.getSession(); 
Object name = session.getAttribute("name"); 

session是安全的,当时他会存在性能问题,在高访问量的场景上分布式环境中甚至会出现网络风暴。

Token

之前是不了解token的,在前一段时间听到这个词的时候研究了一下,发现真的很有必要,特别是在前后端分离的项目中,基于token的认证管理。

关于token的理解之前阅读过这篇博客:https://www.cnblogs.com/xuxinstyle/p/9675541.html

其实主要是记录一下token的实现过程,根据自己的实现过程谈一谈他的理解。

目前使用的过程就是,首先用户请求登录,做了一系列的登录校验之后,数据库中存在登录的用户信息后既可以为当前用户生成唯一的token了。

1.生成Token:

Map<String, Object> claims = ClaimUtil.userToClaims(user); String token = JwtUtil.createToken(claims, Constants.TimeValue.TIME_TWO_HOUR); 

2.创建了token后,可以选择保存在redis或者数据库中,这里采用保存redis后面再保存数据库的方式。

token保存redis后返回唯一的MD5值,这个MD5值可以保存再cookie中,以后每一次前端携带MD5进行校验。

 String tokenKey = Utils.getMd5Value(token); 

3.保存到redis,设置有效期(这里设置为2小时)

redisUtil.set(Constants.User.KEY_TOKEN+tokenKey,token,Constants.TimeValue.TIME_TWO_HOUR); 

4.生成refresh token

JwtUtil.createRefreshToken(userFromDb.getId(),Constants.TimeValue.TIME_TOKEN_ONE_MOUNTH);