Cookie
客户端记录用户登录网站的信息,确定用户身份。它是一小段文本信息,这个文本信息最早由W3C提出,现在的主流浏览器都支持这种机制。(谷歌浏览器是最为标准的遵照W3C规范的浏览器)
每次登录一个网站的时候,相当于我们的浏览器是客户端,向服务端发送各种请求。但是如果我们想买一个东西,俩个用户分别将商品加入购物车。通过HTTP协议完成,服务器获得了俩个用户的请求,这个请求完成相当于数据交换完毕,自然这个连接就会关闭。当其中一个用户准备结账的时候又要重新建立连接,但是服务器不知道是哪一个用户的购物车商品。这就出现了无法跟踪的状况。
因为实际需要保持这种状态,就提供了这种机制。由服务器产生内容,浏览器收到后保存到本地,下一次再进行连接时,就会带着服务器给的信息跟踪到这个位置,它的容量不超过4M。
Session
从上面可以看出Cookie的机制意味着可能在本地被恶意劫持,所以就需要引入具有同样机理的Session,只是Session保存在服务器端,相当于每建立一次连接就建立了这样的会话,而会话的信息也是不超过4M的文本字典数据。Session有一个特点是具有时限性,一般只能保存一段时间,比如你关闭浏览器,再打开你的某个网站的登录信息还在。但是你关闭浏览器半小时再打开就需要重新登录了。
代码语言:javascript复制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。
代码语言:javascript复制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方法。
代码语言:javascript复制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:
代码语言:javascript复制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进行校验。
代码语言:javascript复制 String tokenKey = Utils.getMd5Value(token);
3.保存到redis,设置有效期(这里设置为2小时)
代码语言:javascript复制redisUtil.set(Constants.User.KEY_TOKEN tokenKey,token,Constants.TimeValue.TIME_TWO_HOUR);
4.生成refresh token
代码语言:javascript复制JwtUtil.createRefreshToken(userFromDb.getId(),Constants.TimeValue.TIME_TOKEN_ONE_MOUNTH);