概述
Cookie和Session的前世今生
Web中的Cookie和Session
待补充
Session的创建
我们以一个简单的springboot程序来做实验探究Session对象的产生。
@Controller
@RequestMapping("/hello")
public class CookieSessionTest {
@RequestMapping(value = "/session", method = RequestMethod.GET)
@ResponseBody
public String setCookie(HttpServletRequest request, HttpServletResponse response) {
System.out.println("新的一次请求-----------------");
HttpSession session = request.getSession();
System.out.println("sessionId: " + session.getId() + " session is New: " + session.isNew());
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
System.out.println("cookieName: " + cookie.getName() + " cookieValue:" + cookie.getValue());
}
}
return "world";
}
}
第一次请求
响应中会带有一个set-cookie
第二次请求
请求头中会带有cookie,响应中没有set-cookie了
第三次请求
与第二次情况基本类似
后台输出
新的一次请求-----------------
sessionId: 5FBD4EE9EE11214C3EE752552D83F761 session is New: true
新的一次请求-----------------
sessionId: 5FBD4EE9EE11214C3EE752552D83F761 session is New: false
cookieName: JSESSIONID cookieValue:5FBD4EE9EE11214C3EE752552D83F761
新的一次请求-----------------
sessionId: 5FBD4EE9EE11214C3EE752552D83F761 session is New: false
cookieName: JSESSIONID cookieValue:5FBD4EE9EE11214C3EE752552D83F761
从后台输出结果可以看出,在浏览器第一次访问网站的时候,调用 request.getSession() 后台会创建一个 Session 对象,但此时未创建 Cookie。但从响应头可以看到浏览器有 cookie 了,这表明服务器响应的过程中自动创建了一个Cookie加入 Response 对象。服务端的 session 有Taomcat 容器帮我们管理,我觉得这个自动生成的cookie也是tomcat 帮我们做的。
之前网上说浏览器访问服务器时,会在cookie携带sessionid访问服务器,服务器据此判断用户是否已登录。很长一段时间我一直很疑惑这一点,因为我从未在别人的代码中看到把 sessionid 放到cookie中的痕迹,他们就只是新建了一个 cookie ,再把它放回响应Response中而已。
第二次请求的时候,浏览器会在请求头的cookie中携带刚刚创建的 JSESSIONID。后台调用 request.getSession(),会发现tomcat容器中存在与 cookie所携带JSESSIONID 相同 JSESSIONID 的session,此时getSession() 方法便不再创建Session,而是取出与浏览器关联的那个。
后去请求都与此类似,知道 Cookie或 session的声明周期结束。
Cookie的创建
@RequestMapping(value = "/cookie", method = RequestMethod.GET)
@ResponseBody
public String setCookie(HttpServletRequest request, HttpServletResponse response) {
System.out.println("新的一次请求-----------------");
HttpSession session = request.getSession();
System.out.println("sessionId: " + session.getId() + " session is New: " + session.isNew());
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
for (Cookie cookie : cookies) {
System.out.println("cookieName: " + cookie.getName() + " cookieValue:" + cookie.getValue());
}
}else{
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setComment("success");
cookie.setMaxAge(10000);
response.addCookie(cookie);
}
return "world";
}
第一次请求
实验之前先把浏览器中的cookie清理掉,免得影响此次的结果
第二次请求
从浏览器HTTP头部可以看到我们自己新建的Cookie不会覆盖Tomcat自动创建的。浏览器在拥有特定网站的 cookie时,再去访问时,会在请求中携带所有相关的cookie去访问服务器。
注意:不是http头部cookie: 后面一大串是一个cookie,这一大串中的每一个键值对就是一个cookie。所以request.getCookies()得到的是Cookie数组。并且这个键值对获取值不像Map对象那样以键获取值,因为一个cookie就是 name=value ,所以直接getName() 和 getValue() 就能获取cookie的键和值了。
后台输出
新的一次请求-----------------
sessionId: DD2C964D59864F5295B7A27B5D7E528E session is New: true
新的一次请求-----------------
sessionId: DD2C964D59864F5295B7A27B5D7E528E session is New: false
cookieName: JSESSIONID cookieValue:DD2C964D59864F5295B7A27B5D7E528E
cookieName: JSESSIONID cookieValue:DD2C964D59864F5295B7A27B5D7E528E
Cookie和Session的应用
cookie主要在浏览器端存储用户的信息,session在服务端存储用户的信息。
浏览器可以利用cookie记录用户访问某些网站时需要的一些信息,比如用户名和密码,再次访问网站就可以很快登录了。
cookie登录
可以用cookie记录登录状态,比如用一个 isLogin 字段,当请求到后台时,后台遍历cookie数组,判断是否有此标志,没有则需登录。无须涉及到session,只需伪造cookie即可。
这种登录方式感觉基本没有项目在用,感觉非常容易伪造登录状态。
session登录
可以判断session中是否存在 user 信息判断登录状态。l例如在验证登录的函数中,调用resuest.getSession()如果得到的session中没有 user,表明是新建的session,未登录。那就重定向到登录页面,用setAttribute()把用户信息放到session中保存。然后再由tomcat或自己把此时的sessionid放到cookie中,后续请求根据此sessionid可获取已存在的session,就无须重复登录了。
也可以把用户的账号、权限等信息放到session中,这样无须查询数据库即可获得这些信息,加快了用户的访问速度。
@PostMapping(value = "/login")
@ResponseBody
public ResponseResult login(HttpServletRequest request, HttpServletResponse response, @RequestBody User user) throws Exception{
HttpSession session = request.getSession();
session.setAttribute("userSession",user);
return ResponseResult.success();
}
验证登录状态
public boolean isLogin(HttpServletRequest request, HttpServletResponse response) throws Exception{
HttpSession session = request.getSession();
User user = (User)session.getAttribute("user");
if(user!=null){
return true;
}
//未登录应该重定向到登录页面
response.setHeader("REDIRECT","/login");
return false;
}
session+redis登录
如果系统有多个微服务,每个服务中的tomcat管理自己的session,session存储用户信息。用户访问其他微服务时,可以通过cookie携带sessionid,但是却获取不到用户信息,因为登录模块的session没有同步到其他微服务中,仍需重新登录,这太麻烦了。因此可以把用户信息记录在redis中,各个微服务直接去redis中拿信息即可,拿到用户信息,则免登录,没有,需要登录。
@PostMapping(value = "/loginRedis")
@ResponseBody
public ResponseResult loginByRedis(HttpServletRequest request, HttpServletResponse response, @RequestBody User user) throws Exception{
HttpSession session = request.getSession();
JedisUtil.set("user"+session.getId(),user); //用户信息放进redis
return ResponseResult.success();
}
关键是浏览器真的可以通过cookie携带sessionid访问不同域名的微服务吗?怎么实现cookie跨域呢?
最后
以上就是等待帽子为你收集整理的JavaWeb之Cookie与Session简介Cookie和Session的前世今生Web中的Cookie和SessionCookie和Session的应用的全部内容,希望文章能够帮你解决JavaWeb之Cookie与Session简介Cookie和Session的前世今生Web中的Cookie和SessionCookie和Session的应用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复