Cookie,Session,Token

cookie和seseion都是为了解决访问网站时,登陆了一次,后序访问相关页面不需要再登录,下次登录也不用再输入账号密码的问题

cookie存储在浏览器,session存储在服务端。用一个HashMap进行存储(也可能是存在一台redis服务器上进行分布式session存储),session这个key-value键值对key是sessionId,value是序列化的对象(还是一个User对象),通过这种方式将sessionId和用户数据相关联

用户首次访问网站时,服务器会生成一个唯一的 Session ID,并将这个 Session ID 与用户数据关联(存储在内存中的一个哈希表中,其中键为 Session ID,值为用户数据)

下次客户端再请求的时候就会在cookie中带上这个sessionId,服务端在哈希表中查找与该 Session ID 对应的用户数据,利用用户数据来提供一些个性化服务

如下面所示:

Cookie中存的是名称和值(值就是sessionId)

服务端或者Redis中存的就是sessionId和User对象

cookie就是将账号密码保存在浏览器,然后每次浏览器访问同一个网站,向服务器发送的http请求里面都会带上cookie,由于cookie是保存在浏览器中的,所以叫做客户端会话技术

查看cookie:开发者工具-application-storage-cookie  显示当前网站域名下所有cookie

token:基于cookie传输sessionId变成基于Token传输sessionId

token就是令牌,当客户端发生登陆操作的时候,服务端像下发sessionid植入到cookie中一样,下发一个令牌,交给前端,前端将令牌存储到本地的安全存储里面,下次请求的时候如果需要登录态就在请求中带上令牌

HTTP 协议是无状态的(主要是为了让 HTTP 协议尽可能简单,使得它能够处理大量事务)

HTTP/1.1 引入 Cookie 来保存状态信息

Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销(尤其是在移动环境下)。

// cookie示例
 
    @RequestMapping(path = "/cookie/set", method = RequestMethod.GET)
    @ResponseBody
    public String setCookie(HttpServletResponse response) {
        // 创建cookie
        Cookie cookie = new Cookie("code", CommunityUtil.generateUUID());
        // 设置cookie生效的范围
        cookie.setPath("/community/alpha");
        // 设置cookie的生存时间
        cookie.setMaxAge(60 * 10);
        // 发送cookie
        response.addCookie(cookie);
 
        return "set cookie";
    }
 
    @RequestMapping(path = "/cookie/get", method = RequestMethod.GET)
    @ResponseBody
    public String getCookie(@CookieValue("code") String code) {
        System.out.println(code);
        return "get cookie";
    }
 
    // session示例
 
    @RequestMapping(path = "/session/set", method = RequestMethod.GET)
    @ResponseBody
    public String setSession(HttpSession session) {
        session.setAttribute("id", 1);
        session.setAttribute("name", "Test");
        return "set session";
    }
 
    @RequestMapping(path = "/session/get", method = RequestMethod.GET)
    @ResponseBody
    public String getSession(HttpSession session) {
        System.out.println(session.getAttribute("id"));
        System.out.println(session.getAttribute("name"));
        return "get session";
    }

创建Cookie:

服务器发送的HTTP响应报文的首部中包含 Set-Cookie 首部字段

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]

 浏览器得到响应报文后把 Cookie 内容保存下来,之后对同一个服务器发送HTTP请求的时候,会在Cookie首部字段中将cookie发送给服务器

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

  会话期cookie和持久性cookie

(1)会话期 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。

(2)持久性 Cookie:指定过期时间(Expires)或有效期(max-age)

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

 cookie实际使用:

cookie就是key-value键值对,key是这个cookie的名字,value是这个cookie的值

  (1)   首先是去request请求里面取出所有的cookie

(2)遍历每一个cookie,使用cookie.getName()方法去查找是否有你想要的cookie的名字

(3)使用cookie.getValue()方法取出这个value

      Cookie[]  cookies=request.getCookies();//获取请求里面所有的cookies

      for(Cookie cookie:cookies)
      {
           if(cookie.getName().equals("ticket"))//查找key-value里key为ticket的键值对,取出value
           {
                  String value=cookie.getValue()
                   
            }
      }

而session,在服务器这边会为每一个账户密码创建一个Session ID,

 浏览器会把这个ID添加进cookie里面,以后每访问同一个网站时,浏览器发送请求都会带上这个cookie(session ID包含在cookie里面)

所以其实session就是将cookie里面的用户名+密码改成了session ID而已

jwt(json web token)用户第一次登陆网页,服务器生成一个jwt,服务器不保存这个jwt,而是保存jwt签名的密文,然后将jwt发送给浏览器,浏览器以cookie或者storage的形式进行存储,这样用户每次再访问服务器的时候,就会把cookie(带有jwt)一并发送给服务器

JWT介绍_Pr Young的博客-CSDN博客

持有token就像持有令牌一样允许访问服务器


 

当浏览器发送 HTTP 请求到服务器时,服务器会响应客户端的请求,但当同一个浏览器再次发送请求到该服务器时,服务器并不知道它就是刚才那个浏览器

通常情况下,用户通过浏览器访问 Web 应用时,服务器都需要保存和跟踪用户的状态。例如,用户在某购物网站结算商品时,Web 服务器必须根据请求用户的身份,找到该用户过往所购买的商品

由于 HTTP 协议是无协议的,无法保存和跟踪用户状态,所以需要其他的方案来解决问此题,它就是会话技术。

什么会话?从打开浏览器访问某个网站,到关闭网站的过程,称为一次会话。会话技术是指在会话中,帮助服务器记录用户状态和数据的技术。

会话技术分为两种:

  1. Cookie :客户端会话技术
  2. Session :服务端会话技术

cookie

Http是无状态的

无状态的意思:同一个连接中的两个请求之间没有关系,这就导致用户无法在同一个网站中进行连续的交互。

比如用户访问一个电商网站,用户把某个商品添加到购物车,切换到别的页面之后,又切回来选择了另外一件商品,如果这两次请求之间没有关联,浏览器就无法直到用户最终选择了哪些上商品

Http本身是无状态的,使用cookie可以解决这个问题

服务器发送到用户浏览器,然后保存在用户浏览器本地的一小块数据,下次浏览器向同一服务器再次发起请求的时候就会把这一小块数据携带上一起发送给浏览器

所以cookie用于告知服务器两个请求是不是来自同一个浏览器,用于保持用户的登录状态

cookie使基于无状态的Http协议可以记录稳定的状态信息

cookie就是服务器发送给浏览器的小段文本信息,存储在客户端浏览器的内存中或硬盘上

相当于,在客户端第一次请求后,服务器会下发一个装有客户信息的「小贴纸」,后续客户端请求服务器的时候,带上「小贴纸」,服务器就能认得了

Cookie分为两种:

  1. 会话级别 Cookie(默认):Cookie 保存到浏览器的内存中,浏览器关闭则 Cookie 失效。
  2. 持久的 Cookie:Cookie 以文本文件的形式保存到硬盘上。
cookie.setMaxAge(60*100);//设置cookie的生存时间

  1. 客户端浏览器访问服务器时,服务器通过在 HTTP 响应中增加 Set-Cookie 字段,将数据信息发送给浏览器。
  2. 浏览器将 Cookie 保存在内存中或硬盘上。
  3. 再次请求该服务器时,浏览器通过在 HTTP 请求消息中增加 Cookie 请求头字段,将 Cookie 回传给 Web 服务器。服务器根据 Cookie 信息跟踪客户端的状态。

cookie的缺点是cookie是存在浏览器,存在客户端的,这是不安全的,容易被盗,所以鉴于它安全性不行,所以cookie里面不能存密码

而且如果每次浏览器都要向服务器发送数据,那会造成发送数据过多,对传输性能造成影响

cookie代码实现如下:

public class CookieServlet extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        PrintWriter out=response.getWriter();

        //从请求中获取cookie(cookie可能存在多个)
        Cookie[] cookies=request.getCookies();

        if(cookies!=null)
        {
          //如果存在cookie
            out.write("你上一次访问的时间是:");
            //遍历cookie数组
            for(int i=0;i<cookies.length;i++)
            {
                Cookie cookie=cookies[i];
                //获取cookie的名字,如果cookie的名字和我们想要的cookie名字是一样的
               if(cookie.getName().equals("lastLoginTime"))
               {
                   //获取cookie的值
                   Long lastLoginTime=Long.parseLong(  cookie.getValue());
                   Date date=new Date(lastLoginTime);
                   out.write(date.toLocaleString());
               }

            }

        }
        else
        {
          out.write("这是您第一次访问本站");
        }
        //
        Cookie cookie=new Cookie("lastLoginTime",System.currentTimeMillis()+"");
        
         cookie.setMaxAge(24*60*60);//设置cookie有效期,这里表示有效期为1天

        response.addCookie(cookie);
    }
}

Session

将客户端的信息存在服务器端(数据存放在服务器端更加安全,但是也会增加服务器端的内存压力)

session是依赖于cookie的

用服务器会为每一个用户(浏览器)创建一个Session对象

client端将账户密码发送给srpingboot,然后springbot在mysql里面查一下有没有这个账户密码,如果发现有,就会将结结果返回给client(同时会带上一串字符串作为唯一标识符,这个唯一标识符就叫sessionID),springboot在将这个sessionID传给client之前,会先将这个sessionID保存在mysql或者redis里面(这里以保存在mysql中为例),而client在拿到sessionID之后,就会将它记录到浏览器的cookie里面(浏览器本身的一段内存)

一旦登陆成功之后,client将这个sessionID存到自己的cookie里面,再次发送请求的时候,会带上这个sessionID传给springboot,springboot拿到client的请求,先看请求中是否有sssionID,有的话就拿出来,和springboot中保存的sessionID做比较(有可能springboot里面的sessionID是否过期失效了),如果比较成功,springboot就返回页面

比如你一旦登陆成功了,你访问这个网站的任何页面都不用再输入账户密码了,因为你有sessionID

服务器端的会话技术(存储在服务器端),但是它的实现离不开客户端浏览器和 Cookie 的支持

  1. 当客户端第一次请求会话对象时,服务器会创建一个 Session 对象,并为该 Session 对象分配一个唯一的 SessionID(用来标识这个 Session 对象);
  2. 服务器将 SessionID 以 Cookie(Cookie 名称为:“JSESSIONID”,值为 SessionID 的值)的形式发送给客户端浏览器;
  3. 客户端浏览器再次发送 HTTP 请求时,会将携带 SessionID 的 Cookie 随请求一起发送给服务器;
  4. 服务器从请求中读取 SessionID,然后根据 SessionID 找到对应的 Session 对象

public class SessionServlet extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        //从请求中得到Session
        HttpSession session=request.getSession();

        //给Session中存东西
        session.setAttribute("name","秦疆");

        //获取Session中的Id
        String sessionId=session.getId();

        //判断Session是不是新创建的
        if(session.isNew())//如果是新创建的
        {
            response.getWriter().write("session创建成功,ID:"+sessionId);
        }
        else//Session已经在服务器中存在了
        {
            response.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
        }

    }
}

此时你在浏览器地址栏中输入localhost:8080/SessionServlet会得到:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值