JavaWeb之Cookie与Session简介

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跨域呢?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值