熬夜彻底搞懂Cookie Session Token JWT

Posted 捡田螺的小男孩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了熬夜彻底搞懂Cookie Session Token JWT相关的知识,希望对你有一定的参考价值。

一切的根源就是因为 HTTP 是一个无状态的协议。

token等机制将客户端多次请求关联起来。

想象一下如果没有 cookiesessiontoken 这样的机制,我们在网站上每次点击都需要重新输入密码认证,这样槽糕的体验你还愿意继续用吗?

在讲解cookiesessiontoken前我们先简单讲解两个概念:认证授权

最开始被设计出来是为了弥补HTTP在状态管理上的不足。

  • cookie 存储在客户端:cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
  • cookie 是不可跨域的:每个 cookie 都会绑定单一的域名(包括子域),无法在别的域名下获取使用。
  • 设置 cookie

    服务器向客户端发送 Cookie 是通过 HTTP 响应报文实现的,在 Set-Cookie 中设置需要向客户端发送的cookie,cookie格式如下:

    Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
    cookie 工作流程

    (1)浏览器向服务器发送请求;

    (2)服务器响应请求,向浏览器设置 cookie;

    (3)浏览器将 cookie 存在本地,下一次请求带上该 cookie;

    (4)服务器响应请求。

    cookie 常见属性

    (1)name=value

    键值对,设置 Cookie 的名称及相对应的值。

    (2)domain

    指定 cookie 所属域名,默认是当前域名。如果 cookie 的 domain 设置为 taobao.com,那么 item.taobao.com, order.taobao.com 都是可以共享 cookie 的, 但是访问 tmall.com 就不能共享 cookie 了,这就涉及跨域访问的问题,跨域问题如何解决,这里不展开,有兴趣可以自行搜索。

    (3)path

    指定 cookie 在哪个路径(路由)下生效,默认是 \'/\'。如果设置为 /abc,则只有 /abc 下的路由可以访问到该 cookie,如:/abc/read。

    (4)expires

    指定 cookie 的过期时间(GMT时间格式),到达该时间点后该 cookie 就会自动失效。

    (5)max-age

    HTTP 1.1中定义的,优先级高于 expires 字段。

    max-age 表示 cookie 有效期,单位秒。如果为正数,则该 cookie 在 max-age 秒后失效;如果为负数,该 cookie 为临时 cookie ,关闭浏览器即失效,浏览器也不会以任何形式保存该 cookie ;如果为 0,表示删除该 cookie 。默认为 -1。

    (6)HttpOnly

    如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本读写该 cookie 的信息。

    (7)secure

    该 cookie 是否仅被使用安全协议传输,默认为false。当 secure 值为 true 时,cookie 在 HTTP 中是无效的。

    什么是 session?

    session 翻译过来就是『会话』。用户打开一个浏览器, 点击多个超链接, 访问服务器多个web资源, 然后关闭浏览器, 整个过程称之为一个会话。

    (1)session 的特点

  • session 是另一种记录服务器和客户端会话状态的机制;
  • session 存储在服务器端,一般是文件中,也可以存在数据库或缓存中。
  • session 一般基于 cookie 实现。session 中包含敏感信息存储在服务器端,通常将 sessionId 存储在客户端的 cookie 中,客户端每次请求携带 sessionId 即可识别用户。
  • (2)session 工作流程

    (1)用户第一次请求,提交用户名密码等信息进行登录认证,服务器根据用户提交的信息进行鉴权,鉴权成功后创建 session 对象,并将 sessionId 塞入 cookie 中,浏览器收到响应信息将 cookie 存入本地;

    (2)用户第二次请求,以查看订单信息为例,浏览器自动将当前域名下的 cookie 信息发送给服务端,服务端解析 cookie,获取到 sessionId 后再查找对应的 session 对象,如果 session 对象存在说明用户已经登录,继续下一步操作。

    从上面的流程可知,sessionId 是 cookie 和 session 中间的一道桥梁。

    需要注意:如果客户端禁用了 cookie,还可以通过 url 重写等方法传递 sessionId。

    cookie 和 session 的区别

  • 存储方式:cookie 数据存放在客户的浏览器上,session 数据放在服务器上;
  • 安全性:cookie 是本地存储,不是很安全,别人可以分析存放在本地的 cookie 并进行欺骗;
  • 存储大小:很多浏览器限制单个 cookie 保存的数据不能超过4K,一个站点最多保存20个cookie,session 没有类似的限制;
  • 生存周期:cookie 可设置为长时间保持,Session 一般失效时间较短,一般客户端关闭 session 就会失效。
  • 什么是 token ?

    (1)token 的组成

    token 是验证用户身份的凭证,我们通常叫它:令牌

    最简单的token组成: uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,以哈希算法压缩成一定长的十六进制字符串)

    (2)token 特点

  • 无状态、可扩展
  • 支持移动端设备
  • 支持跨程序调用
  • 安全
  • (3)token 工作流程

    第一步:客户端使用用户名密码或者扫码等形式请求登录;

    第二步:服务端收到请求后进行鉴权,鉴权成功后服务端会生成一个 token 并发送给客户端,客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里;

    第三步:客户端下一次向服务端请求资源的时候需要带着存储的 token;

    第四步:服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据。

    需要注意:

  • 客户端请求时可以将 token 放到 HTTP 的 Header 里;
  • 基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据。
  • 用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库
  • 什么是 JWT?

    (1)JWT 是标准 化的 token

    从本质上讲 JWT 也是一种 token,只不过 JWT 是被大家广泛接受的标准。

    JWT 即:Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准(RFC 7519)。

    JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息。

    (2)JWT 的组成

    JWT 共有三部分组成:

  • 第一部分我们称它为头部(header)
  • 第二部分我们称其为载荷(payload, 类似于飞机上承载的物品)
  • 第三部分是签证(signature)
  • 在https://jwt.io/网站上可以解析一个已知的 JWT:

  • header
  • jwt的头部承载两部分信息:声明类型,这里是jwt;声明加密的算法,通常直接使用 HMAC SHA256;

  • playload
  • 载荷就是存放有效信息的地方。主要包含三个部分:标准中注册的声明公共的声明私有的声明

  • signature
  • jwt 的第三部分是一个签名信息,这个签证信息由三部分组成:header (base64后的);payload (base64后的);secret。

    (3)JWT 的特点

  • 不在 jwt 的 payload 部分存放敏感信息,因为该部分是客户端可解密的部分。
  • 保护好 secret 私钥,该私钥非常重要。
  • 如果可以,请使用 https 协议。
  • 总结

    在分布式微服务技术日趋流行的今天,大型网站的设计都尽量避免使用 session 实现 HTTP 状态化。

    session简单粗暴,在服务端维护会话信息,在客户端保存session id,服务端能够轻易地把会话控制在自己的手中,但服务集群化产生了session共享的负担;

    jwt(token)只在客户端保存会话信息,服务端通过密钥校验会话,(相比session)拿时间换空间,卸下了服务端集群共享会话信息的负担,同时也加大了服务端控制会话的难度。

    大家在工作中使用哪种方案,欢迎在留言区讨论。

    -- End --

    求鼓励,『点赞』、『在看』、『分享』三连支持一下呗,下期见~

    彻底搞懂CookieSessionJWT和Token(强烈推荐)《彻底搞懂CookieSessionJWT和Token|CSDN创作打卡》

    文章目录

    引入:http是一个无状态协议?怎么解决呢?

    无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。HTTP无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,两种用于保持HTTP连接状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session。

    一、Cookie和Session

    cookie中可以用来保存服务端返回的一些用户信息的,每一次的请求,都会携带这些cookie。服务端从请求头中取到cookie中的信息,就可以识别本次请求的来源,http就变成有状态的了。

    由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的。cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使session, session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie

    1.1 cookie 注意事项:

    1、cookie存放在客户端(浏览器端),所以是不安全的,人为可以清除。cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
    2、cookie有过期时间设定。如果不设置过期时间,说明这个cookie就是当前浏览器的会话时间,浏览器关了,cookie就不存在了。如果有过期时间,cookie就会存储到硬盘上,浏览器关闭不影响cookie。下次打开浏览器,cookie还存在
    3、cookie可以被用户禁止
    4、cookie有大小的限制,一个浏览器能创建的 Cookie 数量最多为 300 个,并且每个不能超过 4KB,每个 Web 站点能设置的 Cookie 总数不能超过 20 个。
    5、cookie 是不可跨域的: 每个 cookie 都会绑定单一的域名,无法在别的域名下获取使用,一级域名和二级域名之间是允许共享使用的(靠的是 domain)。

    1.2 cookie 重要的属性

    属性名描述
    String name该Cookie的名称。Cookie一旦创建,名称便不可更改 ,必须是字符串类型
    Object value该Cookie的值。如果值为Unicode字符,需要为字符编码。如果值为二进制数据,则需要使用BASE64编码
    int maxAge该Cookie失效的时间,单位秒。如果为正数,则该Cookie在maxAge秒之后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。如果为0,表示删除该Cookie。默认为–1。比expires好用
    int expires设置Cookie过期时间,在设置的某一个时间后该cookie就会失效。
    boolean secure该Cookie是否仅被使用安全协议传输。安全协议。安全协议有HTTPS,SSL等,在网络上传输数据之前先将数据加密。默认为false。当secure值为true时,cookie在HTTP中是无效的,在HTTPS中才有效
    String path该Cookie的使用路径。如果设置为“/love/”,则只有contextPath为“/love”的程序可以访问该Cookie。如果设置为“/”,则本域名下contextPath都可以访问该Cookie。注意最后一个字符必须为“/”
    String domain决定该cookie作用在哪个域。默认是当前域名
    int version该Cookie使用的版本号。0表示遵循Netscape的Cookie规范,1表示遵循W3C的RFC 2109规范
    HttpOnly该cookie不能通过js读取,但还是能通过Application中手动修改cookie,所以只是在一定程度上防止XSS攻击,并不是绝对的安全

    1.3 session 注意事项:

    1、session是将用户信息储存在服务器上面,如果访问服务器的用户越来越多,那么服务器上面的session也越来越多, session会对服务器造成压力,影响服务器的负载.如果Session内容过于复杂,当大量客户访问服务器时还可能会导致内存溢出。
    2、用户信息丢失, 或者说用户访问的不是这台服务器的情况下,就会出现数据库丢失。这就是它的弊端。现在有一些技术,例如session共享、iphash、session持久等也可以解决上述问题。
    3、当Cookie被禁止,Session也被禁止。cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中。
    4、session 是基于 cookie 实现的,session 存储在服务器端,sessionId 会被存储到客户端的cookie 中

    根据以上流程我们可以看出,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。但这种模式最大的问题是,没有分布式架构,无法支持横向扩展。如果使用一个服务器,该模式完全没有问题。但是,如果它是服务器群集或面向服务的跨域体系结构的话,则需要一个统一的session数据库库来保存会话数据实现共享,这样负载均衡下的每个服务器才可以正确的验证用户身份。
    解决这个问题我们可以使用token,具体看下面对token的讲解

    1.4 Cookie 和 Session 的区别:

    根据上面的解释,我们在来最终总结一下它们大体的区别:
    安全性: Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。
    存取值的类型不同:Cookie 只支持存字符串数据,Session 可以存任意数据类型。
    有效期不同: Cookie 可设置为长时间保持,比如我们经常使用的记住我(默认登录)等功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。
    存储大小不同: 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。

    注意点:
    现在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用,如果只用cookie不用session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大。
    用session只需要在客户端保存一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的
    简而言之, session 就像用户信息表, 里面包含了用户的信息(姓名、状态等等). 而 cookie 就是用户通行证

    二、token(令牌)

    Token顾名思义就是令牌、凭证、钥匙,只有这把钥匙,你才能打开门。Token一般都是服务端生成,比如一个web系统,用户登录的时候,服务端校验用户名密码通过以后,会生成一个token,然后将token返回给客户端,客户端会将token保存下来(放到 HTTP 的 Header 里), 后续所有的请求都会携带这个token。服务端会判断当前token是否存在已经是否过期。如果token不存在或者过期就会拒绝本次请求。

    简单 token 的组成: uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token 的前几位以哈希算法压缩成的一定长度的十六进制字符串)

    2.1 token优势

    1. Token 完全由应用管理,所以它可以避开同源策略
    2. 安全性。Token 可以避免 CSRF攻击(因为不需要 cookie 了)
    CSRF攻击(跨站请求伪造)攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…造成的问题包括:个人隐私泄露以及财产安全。(CSRF攻击具体是什么大家如果想要了解可以评论区讨论哦)
    3.无状态、可扩展,可以在多个服务间共享
    4.多平台跨域:CORS(跨域资源共享)对应用程序和服务进行扩展的时候,需要介入各种各种的设备和应用程序。只要用户有一个通过了验证的token,数据和资源就能够在任何域上被请求到。

    2.2 token 的身份验证流程

    三、基于JWT实现的Token认证方案

    创建token的时候,我们可以设定一些选项。但是标准的用法会在JSON Web Tokens简称JWT体现。
    JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案。

    3.1 JWT组成部分

    JSON Web Tokens令牌以紧凑的形式由三部分组成,这些部分由点 (. )分隔,分别是:

    Header:标头
    Payload: 有效载荷
    Signature: 签名


    该对象为一个很长的字符串,字符之间通过"."分隔符分为三个子串。
    每一个子串表示了一个功能块,总共有以下三个部分:JWT头、有效载荷和签名

    3.1.1 Header:标头

    标头通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256或RSA。
    例如:

     此JSON被Base64Url编码以形成JWT的第一部分。
    
    "alg": "HS256",表示签名使用的算法,默认为HMAC SHA256(写为HS256)
    "typ": "JWT"表示令牌的类型,JWT令牌统一写为JWT
    
    

    3.1.2 Payload:有效载荷

    有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认
    字段供选择。

    iss:发行人
    exp:到期时间
    sub:主题
    aud:用户
    nbf:在此之前不可用
    Iat:发布时间
    jti:JWT ID用于标识该JWT

    除以上默认字段外,我们还可以自定义私有字段,有效负载示例可以是:

    
    "sub": "9876543210",
    "name": "Mr Fen",
    "admin": true
    请注意,默认情况下JWT是未加密的,任何人都可以解读其内容,因此不要构建隐私信息字段,存放保密信息,以防止信息泄露。
    
    

    3.1.3 Payload:签名

    要创建签名部分,您必须获取编码的头、编码的负载、密钥、头中指定的算法,并对其进行签名。
    例如,如果要使用HMAC SHA256算法,则将通过以下方式创建签名:

    HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(claims), secret)
    

    3.2 什么时候应该使用 JWT?

    1、身份验证,这是使用JWT的最常见方案。一旦用户登录,每个后续请求将包括JWT,从而允许用户访问该令牌允许的路由,服务和资源。单一登录是当今广泛使用JWT的一项功能,因为它的开销很小并且可以在不同的域中轻松使用。
    2、信息交换,JWT令牌是在各方之间安全地传输信息的一种好方法。因为可以对JWT进行签名(例如,使用公钥/私钥对),所以您可以确定发件人是本人。另外,由于签名是使用标头和有效负载计算的,因此您还可以验证内容是否未被篡改。

    3.3 JWT和Token有什么关系?

    token是按照一定规则生成的字符串,包含用户信息。
    一般我们会采用标准的用法JWT。
    JWT就是给我们规定好了规则,使用JWT可以生成字符串,包含用户信息。

    以上是关于熬夜彻底搞懂Cookie Session Token JWT的主要内容,如果未能解决你的问题,请参考以下文章

    彻底搞懂CookieSessionJWT和Token(强烈推荐)《彻底搞懂CookieSessionJWT和Token|CSDN创作打卡》

    cookie是啥?有啥用?cookie详解,一篇文章彻底搞懂cookie

    cookie和session了解吗

    关于session和cookie

    彻底搞懂cookie

    5分钟搞懂:session与cookie