授权认证登录之 Cookie、Session、Token、JWT 详解

news2025/1/21 2:49:14

授权认证登录之 Cookie、Session、Token、JWT 详解

  • 一、先了解几个基础概念
    • 什么是认证(Authentication)
    • 什么是授权(Authorization)
    • 什么是凭证(Credentials)
  • 二、Cookie
    • 1、了解 Cookie
    • 2、cooker的创建
    • 2、cooker的携带
    • 3、cooker的配置属性
      • 3.1 生命周期
      • 3.2 作用范围
      • 3.3 多级域名
      • 3.4 Path
      • 3.5 个数和大小限制
      • 3.6 Priority优先级
      • 3.7 HttpOnly
      • 3.8 跨站与Samesite设置
    • 3、cookie、sessionStorage、localStorage 区别?
  • 三、 Session
    • 1、什么是session
    • 2、session 认证流程:
  • 四、Cookie 和 Session 的区别
  • 五、Token(令牌)
    • Acesss Token
    • Refresh Token
  • 六、Token 和 Session 的区别
  • 七、什么是 JWT
    • 1. JWT 的原理
    • 2. JWT 的数据结构
  • 八、Token 和 JWT 的区别
  • 九、要注意的问题
    • 使用 session 时需要考虑的问题
    • 使用 JWT 时需要考虑的问题
    • 使用加密算法时需要考虑的问题
    • **只要关闭浏览器 ,session 真的就消失了?**
  • 总结:
    • (一)cooker + session
    • (二) token
    • (三)传统token方式和JWT在认证方面存在几个显著的差异:

一、先了解几个基础概念

什么是认证(Authentication)

通俗地讲就是验证当前用户的身份。

互联网中的认证:

  • 用户名密码登录
  • 邮箱发送登录链接
  • 手机号接收验证码
  • 只要你能收到邮箱/验证码,就默认你是账号的主人

什么是授权(Authorization)

用户授予第三方应用访问该用户某些资源的权限。

实现授权的方式有:cookie、session、token、OAuth。

什么是凭证(Credentials)

实现认证和授权的前提是需要一种媒介(证书)来标记访问者的身份。

在互联网应用中,一般网站(如掘金)会有两种模式,游客模式和登录模式。游客模式下,可以正常浏览网站上面的文章,一旦想要点赞/收藏/分享文章,就需要登录或者注册账号。当用户登录成功后,服务器会给该用户使用的浏览器颁发一个令牌(token),这个令牌用来表明你的身份,每次浏览器发送请求时会带上这个令牌,就可以使用游客模式下无法使用的功能。

二、Cookie

1、了解 Cookie

  • Cookie 最开始被设计出来是为了弥补HTTP在状态管理上的不足。HTTP 协议是一个无状态协议,客户端向服务器发请求,服务器返回响应,故事就这样结束了,但是下次发请求如何让服务端知道客户端是谁呢?这种背景下,就产生了 Cookie。
  • cookie 存储在客户端: cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。因此,服务端脚本就可以读、写存储在客户端的cookie的值。
  • cookie 是不可跨站的: 每个 cookie 都绑定在特定的域名下(绑定域名下的子域都是有效的),无法在别的域名下获取使用,同域名不同端口也允许共享。

可以在浏览器控制台的 Application 面板查看Cookie:
在这里插入图片描述

2、cooker的创建

正常来说 90%为服务端设置cookie

理由:

服务端设置cookie和客户端直接设置cookie有以下几个主要区别:
(一)安全性和隐私:
服务端设置:服务端设置cookie通常更加安全,因为它涉及到服务器的验证和授权。服务端可以设置cookie的HttpOnly属性,这样JavaScript就无法访问这个cookie,从而减少了XSS(跨站脚本)攻击的风险。此外,服务端可以设置Secure属性,强制cookie只能通过HTTPS协议传输,增加了数据的安全性。
客户端设置:客户端直接设置cookie相对较为不安全,因为任何可以修改客户端代码或状态的攻击者都可能篡改或窃取cookie。此外,客户端设置的cookie可能会暴露给第三方脚本或扩展程序,增加了隐私泄露的风险。
(二)控制和灵活性:
服务端设置:服务端完全控制cookie的生成、发送和更新。服务端可以设置cookie的过期时间、作用域(path)、域名等属性,还可以根据用户的身份和权限动态生成cookie。
客户端设置:客户端对cookie的控制相对有限。虽然JavaScript可以通过document.cookie API来读取、修改或删除cookie,但这些操作通常受到同源策略的限制,并且无法设置HttpOnly和Secure等属性。
(三)用途和目的:
服务端设置:服务端通常使用cookie来跟踪用户的会话状态、身份验证信息、个性化设置等。这些cookie对于服务器的正常运行和提供个性化服务至关重要。
客户端设置:客户端设置cookie的用例较少,通常用于临时存储一些用户设置或偏好,例如网页的主题、字体大小等。这些设置通常不会影响到服务器的运行或安全性。
(四)兼容性和稳定性:
服务端设置:服务端设置的cookie在各种浏览器和平台上都有良好的兼容性和稳定性,因为它们遵循HTTP协议的标准规范。
客户端设置:客户端设置的cookie可能会受到浏览器实现和版本差异的影响,导致兼容性问题。此外,如果客户端代码存在错误或漏洞,可能会导致cookie的设置或读取失败,影响用户体验和数据安全性。

综上所述,服务端设置cookie通常更加安全、可控和灵活,适用于需要跟踪用户状态、身份验证等场景。而客户端直接设置cookie则更多地用于临时存储用户设置或偏好,其安全性和可控性相对较低。在实际开发中,建议尽可能通过服务端来设置和管理cookie,以确保数据的安全性和系统的稳定性。

以下是一个简单的示例,展示了在Java后端(例如使用Spring框架)中,
在用户登录成功后如何设置会话Cookie:

import javax.servlet.http.Cookie;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import javax.servlet.http.HttpSession;  
import org.springframework.web.servlet.HandlerAdapter;  
import org.springframework.web.servlet.ModelAndView;  
  
// 假设这是一个处理用户登录的Controller方法  
public ModelAndView handleLogin(HttpServletRequest request, HttpServletResponse response, String username, String password) {  
    // 模拟验证用户名和密码的过程  
    if ("admin".equals(username) && "password".equals(password)) {  
        // 登录成功,获取HttpSession对象  
        HttpSession session = request.getSession();  
          
        // 可以在session中存储用户信息,例如用户名  
        session.setAttribute("username", username);  
          
        // 创建一个新的Cookie来存储session的id  
        Cookie sessionCookie = new Cookie("JSESSIONID", session.getId());  
          
        // 设置Cookie的有效路径,通常设置为根路径,使得Cookie在整个应用中都可用  
        sessionCookie.setPath("/");  
          
        // 设置Cookie的HttpOnly属性为true,增加安全性  
        sessionCookie.setHttpOnly(true);  
          
        // 设置Cookie的最大生存时间,如果不设置则默认为会话级别,即浏览器关闭时过期  
        // sessionCookie.setMaxAge(-1); // 会话级别,默认行为  
          
        // 将Cookie添加到响应中  
        response.addCookie(sessionCookie);  
          
        // 返回成功登录的视图或者其他响应  
        ModelAndView modelAndView = new ModelAndView("loginSuccess");  
        modelAndView.addObject("message", "登录成功!");  
        return modelAndView;  
    } else {  
        // 登录失败,返回错误视图或响应  
        ModelAndView modelAndView = new ModelAndView("loginFailure");  
        modelAndView.addObject("message", "用户名或密码错误!");  
        return modelAndView;  
    }  
}

2、cooker的携带

借助 HTTP 头、浏览器能力,cookie 可以做到前端无感知。

一般过程是这样的:

  • 浏览器收到后端传过来的 Cookie后,会将Cookie保存下来
  • 后续浏览器发起请求时,会自动把 cookie 通过 HTTP 请求头的 Cookie 字段,带给接口

以下是后端返回的set-Cooker(Response Headers)
在这里插入图片描述
以下是后续请求的入参cooker(Request Headrs)
在这里插入图片描述

3、cooker的配置属性

属性含义
NameCookie的名称
Value对应名称的值
DomainCookie的域名
Path Cookie生效的路径
Expires过期时间,过了这个时间后Cookie失效
Max-age生效时间,表示Cookie在多长时间后失效
SizeCookie的长度,为name和value的长度和
HttpOnly防止通过JavaScript访问Cookie
Secure只在HTTPS协议的情况下才会将Cookie传到后端
SameSite是否允许跨站请求时发送Cookie
Partitioned第三方Cookie分区
Priority优先级

3.1 生命周期

Cookie是有生命周期的,在设置Cookie值时,可以同时设置有效期。当超过了这个有效期之后,Cookie便会失效,前端请求时,不会携带过期的Cookie。

Cookie的有效期有三种类型:

(一) Session
这里的Session并不是存储在服务端的Session,而是指浏览器会话。如果Cookie的有效期为Session,一般关闭会话时,Cookie便会失效;而一些浏览器重启时,也会将会话恢复,此时Cookie并不会失效。

(二) Expires
Expires表示过期时间,是一个确定的日期时间。例如Expires=Wed, 21 Oct 2015 07:28:00 GMT。当浏览器端本地的当前时间超过这个时间时,Cookie便会失效。

(三) Max-age
Max-age表示Cookie的存活时间,以秒作为单位。例如Max-age=3000。当获取到该Cookie后开始倒计时,3000秒之后便失效。

注意:上述的生命周期都是服务端指定的。如果设置了Expires,则是把服务器时间和浏览器本地时间相比较,如果时间不同步,配置就会出现问题。而Max-age设置的是秒数,始终是浏览器本地时间自己相比较,不会出现时间不同步的问题。

3.2 作用范围

作用范围主要由Domain和Path两个属性来控制。

(一)Domain
Domain用来设置Cookie作用的域名,即Cookie在哪个网站生效。默认情况下,生效的域名为当前访问的域名。例如我们在jzplp.com设置的Cookie,就只能限制该网站内使用。

3.3 多级域名

如果访问的网站有多级域名,则Cookie默认仅在访问的多级域名内生效。如果希望在更大范围内生效,可以指定域名。

例如我们在a.jzplp.com下设置的Cookie,就只在这个域名下生效。但是如果我们在设置cookie时同时设置了domain=jzplp.com,则该Cookie可以在jzplp.com下的任何域名内生效。比如:

  • jzplp.com
  • a.jzplp.com
  • b.jzplp.com
  • c.d.jzplp.com

3.4 Path

有时候,我们希望Cookie仅仅在部分路径下生效,就可以使用Path进行限制。这里的路径就是网站的路由。默认的path=/,即在所有路径下生效。 如果设置了path=/abc,则只在/abc路径下生效。比如:

  • jzplp.com 不生效
  • jzplp.com/abc 生效
  • jzplp.com/abc/def 生效
  • jzplp.com/qaz 不生效
  • jzplp.com/qaz/abc 不生效

3.5 个数和大小限制

限制规则
不同的浏览器允许的Cookie大小并不相同,通常的限制为: - 个数限制: 20~50 - 总大小限制: 4KB左右

3.6 Priority优先级

当Cookie的数量超过限制时,路蓝旗会清除一部分Cookie。清除哪些合适呢?Priority属性用来定义Cookie的优先级,低优先级的Cookie会优先被清除。

Priority属性有三种: Low, Medium, High

3.7 HttpOnly

通常的Cookie在客户端(一般指浏览器)是可以通过脚本代码(一般指js)访问的。方式可见JavaScript中操作Cookie。

如果设置了HttpOnly属性,则该Cookie在浏览器中无法通过js代码访问,经过我测试也无法写入。这样可以防止窃取Cookie信息,一般用来防止XSS攻击。

3.8 跨站与Samesite设置

Samesite是Cookie的跨站属性,也可以看做是“更高级”的作用范围设置。
部分内容参考了几篇文章:SameSite Cookie,防止CSRF攻击, Cookie 的 SameSite 属性

3、cookie、sessionStorage、localStorage 区别?

  1. 共同点都是存储在浏览器本地的,都遵循同源原则(sessionStorage还必须是同一个页面)
  2. cookie是由服务端写入的,后两者是前端写入的。
  3. cookie的生命周期是服务端设置好的,sessionStorage在浏览器关闭后就被删除,localStorage生命周期一直存在除非手动删除
  4. cookie的存储空间只有4KB,后两者为5M
  5. 在前端请求后端时会自动携带cookie,后两者不会
  6. cookie一般用于存储登录的信息(如sessionId,token)
    sessionStorage可以用于检测用户是否时页面刷新进入的
    localStorage一般用于存储不易改变的数据

【参考文章】
【1】https://zhuanlan.zhihu.com/p/643916120
【2】https://blog.csdn.net/huangpb123/article/details/109107461

三、 Session

1、什么是session

  • session 是另一种记录服务器和客户端会话状态的机制
  • session 是基于 cookie 实现的,session 存储在服务器端,sessionId 会被存储到客户端的cookie 中

2、session 认证流程:

在这里插入图片描述

  • 用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session
  • 请求返回时将此 Session 的唯一标识 SessionID 返回给浏览器
  • 浏览器接收到服务器返回的 SessionID 后,会将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名
  • 当用户第二次访问服务器的时候,请求会自动把此域名下的 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。

根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

四、Cookie 和 Session 的区别

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

五、Token(令牌)

Acesss Token

  • 访问资源接口(API)时所需要的资源凭证
  • 简单 token 的组成: uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token 的前几位以哈希算法压缩成的一定长度的十六进制字符串)

服务器对 Token 的存储方式:

  1. 存到数据库中,每次客户端请求的时候取出来验证(服务端有状态)
  2. 存到 redis 中,设置过期时间,每次客户端请求的时候取出来验证(服务端有状态)
  3. 不存,每次客户端请求的时候根据之前的生成方法再生成一次来验证(JWT,服务端无状态)
  • 特点:
    • 服务端无状态化、可扩展性好
    • 支持移动端设备
    • 安全
    • 支持跨程序调用
  • token 的身份验证流程:

在这里插入图片描述

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端
  4. 客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据
  • 每一次请求都需要携带 token,需要把 token 放到 HTTP 的 Header 里
  • token 完全由应用管理,所以它可以避开同源策略

注意:登录时 token 不宜保存在 localStorage,被 XSS 攻击时容易泄露。所以比较好的方式是把 token 写在 cookie 里。为了保证 xss 攻击时 cookie 不被获取,还要设置 cookie 的 http-only。这样,我们就能确保 js 读取不到 cookie 的信息了。再加上 https,能让我们的请求更安全一些。

Refresh Token

  • 另外一种 token——refresh token
  • refresh token 是专用于刷新 access token 的 token。如果没有 refresh token,也可以刷新 access token,但每次刷新都要用户输入登录用户名与密码,会很麻烦。有了 refresh token,可以减少这个麻烦,客户端直接用 refresh token 去更新 access token,无需用户进行额外的操作。

在这里插入图片描述

  • Access Token 的有效期比较短,当 Acesss Token 由于过期而失效时,使用 Refresh Token 就可以获取到新的 Token,如果 Refresh Token 也失效了,用户就只能重新登录了。
  • Refresh Token 及过期时间是存储在服务器的数据库中,只有在申请新的 Acesss Token 时才会验证,不会对业务接口响应时间造成影响,也不需要向 Session 一样一直保持在内存中以应对大量的请求。

六、Token 和 Session 的区别

  • Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。
  • Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重复攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态。
  • 如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了。

七、什么是 JWT

  • JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。
  • 是一种认证授权机制
  • JWT 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上。
  • 可以使用 HMAC 算法或者是 RSA 的公/私秘钥对 JWT 进行签名。因为数字签名的存在,这些传递的信息是可信的。

1. JWT 的原理

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,返回给用户,就像下面这样。

  1. {

  2. “姓名”: “张三”,

  3. “角色”: “管理员”,

  4. “到期时间”: “2018年7月1日0点0分”

  5. }

以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。
在这里插入图片描述

JWT 认证流程:

  • 用户输入用户名/密码登录,服务端认证成功后,会返回给客户端一个 JWT

  • 客户端将 token 保存到本地(通常使用 localstorage,也可以使用 cookie)

  • 当用户希望访问一个受保护的路由或者资源的时候,需要请求头的 Authorization 字段中使用Bearer 模式添加 JWT,其内容看起来是下面这样

    Authorization: Bearer

  • 服务端的保护路由将会检查请求头 Authorization 中的 JWT 信息,如果合法,则允许用户的行为

  • 因为 JWT 是自包含的(内部包含了一些会话信息),因此减少了需要查询数据库的需要

  • 因为 JWT 并不使用 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域问题

  • 因为用户的状态不再存储在服务端的内存中,所以这是一种无状态的认证机制

2. JWT 的数据结构

实际的 JWT 大概就像下面这样:
在这里插入图片描述

它是一个很长的字符串,中间用点(.)分隔成三个部分。

JWT 的三个部分依次如下:

  • Header(头部)
  • Payload(负载)
  • Signature(签名)

JWT详细数据结构

生成 JWT

  • https://jwt.io/
  • https://www.jsonwebtoken.io/

八、Token 和 JWT 的区别

相同:

  • 都是访问资源的令牌
  • 都可以记录用户的信息
  • 都是使服务端无状态化
  • 都是只有验证成功后,客户端才能访问服务端上受保护的资源

区别:

  • Token:服务端验证客户端发送过来的 Token 时,还需要查询数据库获取用户信息,然后验证 Token 是否有效。
  • JWT: 将 Token 和 Payload 加密后存储于客户端,服务端只需要使用密钥解密进行校验(校验也是 JWT 自己实现的)即可,不需要查询或者减少查询数据库,因为 JWT 自包含了用户信息和加密的数据。

九、要注意的问题

使用 session 时需要考虑的问题

  • 将 session 存储在服务器里面,当用户同时在线量比较多时,这些 session 会占据较多的内存,需要在服务端定期的去清理过期的 session
  • 当网站采用集群部署的时候,会遇到多台 web 服务器之间如何做 session 共享的问题。因为 session 是由单个服务器创建的,但是处理用户请求的服务器不一定是那个创建 session 的服务器,那么该服务器就无法拿到之前已经放入到 session 中的登录凭证之类的信息了。
  • 当多个应用要共享 session 时,除了以上问题,还会遇到跨域问题,因为不同的应用可能部署的主机不一样,需要在各个应用做好 cookie 跨域的处理。
  • sessionId 是存储在 cookie 中的,假如浏览器禁止 cookie 或不支持 cookie 怎么办? 一般会把 sessionId 跟在 url 参数后面即重写 url,所以 session 不一定非得需要靠 cookie 实现
  • 移动端对 cookie 的支持不是很好,而 session 需要基于 cookie 实现,所以移动端常用的是 token

使用 JWT 时需要考虑的问题

  • 因为 JWT 并不依赖 Cookie 的,所以你可以使用任何域名提供你的 API 服务而不需要担心跨域问题
  • JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。
  • JWT 不加密的情况下,不能将秘密数据写入 JWT。
  • JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。
  • JWT 最大的优势是服务器不再需要存储 Session,使得服务器认证鉴权业务可以方便扩展。但这也是 JWT 最大的缺点:由于服务器不需要存储 Session 状态,因此使用过程中无法废弃某个 Token 或者更改 Token 的权限。也就是说一旦 JWT 签发了,到期之前就会始终有效,除非服务器部署额外的逻辑。
  • JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。
  • JWT 适合一次性的命令认证,颁发一个有效期极短的 JWT,即使暴露了危险也很小,由于每次操作都会生成新的 JWT,因此也没必要保存 JWT,真正实现无状态。
  • 为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

使用加密算法时需要考虑的问题

  • 绝不要以明文存储密码
  • 永远使用 哈希算法 来处理密码,绝不要使用 Base64 或其他编码方式来存储密码,这和以明文存储密码是一样的,使用哈希,而不要使用编码。编码以及加密,都是双向的过程,而密码是保密的,应该只被它的所有者知道, 这个过程必须是单向的。哈希正是用于做这个的,从来没有解哈希这种说法,但是编码就存在解码,加密就存在解密。
  • 绝不要使用弱哈希或已被破解的哈希算法,像 MD5 或 SHA1 ,只使用强密码哈希算法。
  • 绝不要以明文形式显示或发送密码,即使是对密码的所有者也应该这样。如果你需要 “忘记密码” 的功能,可以随机生成一个新的 一次性的(这点很重要)密码,然后把这个密码发送给用户。

只要关闭浏览器 ,session 真的就消失了?

不对。浏览器关闭时,是不会主动去通知服务器的。
之所以会有这种错觉,是大部分 session 机制都使用会话 cookie 来保存 sessionId,而关闭浏览器后这个 cookie 就消失了,再次连接服务器时也就无法找到原来的 session。
如果服务器设置的 cookie 被保存在硬盘上,或者使用某种手段改写浏览器发出的 HTTP 请求头,把原来的 sessionId 发送给服务器,则再次打开浏览器仍然能够打开原来的 session。
恰恰是由于关闭浏览器不会导致 session 被删除,迫使服务器为 session 设置了一个失效时间,当距离客户端上一次使用 session 的时间超过这个失效时间时,服务器就认为客户端已经停止了活动,才会把 session 删除以节省存储空间。

【参考文章】
【1】https://www.cnblogs.com/gaodi2345/p/13864532.html

总结:

(一)cooker + session

一、存储方面:
Cookie 存在客户端
Session 默认情况下,是存储在服务器的一个文件中(不是内存),文件名以sess_为前缀,后跟Session ID。(虽然也可以放到数据库、redis中,但是也没必要了)
二、安全性方面:
session > cooker
(1)session的sessionID是放在cookie里,要想功破session的话,第一要功破cookie。
(2)sessionID是加密的,第二次session_start的时候,前一次的sessionID就没有用了,
session过期时sessionid也会失效,想在短时间内功破加了密的 sessionID很难。
session是针对某一次通信而言,会话结束session也就随着消失了.
而真正的cookie存在于客户端硬盘上的一个文本文件.
三、可定制性方面:
Session可以被自定义,允许应用程序开发人员或管理员选择Session的持续时间、大小、编码等参数。

(二) token

一、存储方面:
要么数据库,要么redis
二、安全性方面:
本质是一个32位的uuid,
1.如果没有和配合cooker的话, token 应该是保存在 localStorage(虽然安全性不高,也要分情况),同时需要前端那边每次调用都要去设置个头部(一般都爱用Authorization)入参进来
示例如下:

const token = localStorage.getItem('token');  
  
fetch('https://example.com/api/resource', {  
  method: 'GET',  
  headers: {  
    'Authorization': `Bearer ${token}`, // 假设token是JWT格式  
  },  
})  
.then(response => response.json())  
.then(data => console.log(data))  
.catch(error => console.error('Error:', error));

2.如果配合Cookie的话,就默认自动设置到请求头部的Cookie上面。
例如,一个HTTP请求头可能看起来像这样:

GET /api/resource HTTP/1.1  
Host: example.com  
Cookie: token=your_token_value; another_cookie=another_value

三、可定制性方面
一般来说是需要redis配合一下,大致步骤一般为以下情况
前端点击登陆,服务器验证账号密码成功
服务器生成令牌,本质是一个32位的uuid
将该令牌存到数据库或redis中,key是uuid,value是userId
把令牌返给客户端,客户端把令牌存在cookie中。
下次请求的时候就把令牌放在请求头里带上
从redis中验证该令牌是否过期
获取value内容userId
根据userId查询用户信息,再返回客户端

(三)传统token方式和JWT在认证方面存在几个显著的差异:

1.存储与验证机制:

  • 传统token方式:在用户登录成功后,服务端会生成一个随机的token并发送给用户,同时这个token会在服务端(如数据库或缓存)中保存一份。每当用户再次访问时,都需要携带这个token。服务端接收到token后,会到数据库或缓存中进行校验,确认token是否超时或合法。
  • JWT方式:在用户登录成功后,服务端使用JWT生成一个随机的token并发送给用户。与传统的token方式不同,服务端不需要保留这个token。当用户再次访问时,携带的token由服务端通过JWT进行校验,确认其是否超时或合法。

2.安全性:

  • JWT使用签名来验证token的有效性,确保token在传输过程中没有被篡改。而传统的token方式通常没有这种机制,只能通过验证token的合法性来确保安全性。
    扩展性与信息存储:
  • JWT可以存储更多的信息,例如用户的角色、权限等。这使得JWT具有更高的扩展性。而传统的token方式通常只能存储有限的信息。
    3.无状态性:
  • JWT是无状态的,这意味着服务端不需要保存任何用户信息,只需验证JWT的签名即可。这种无状态性使得JWT特别适用于分布式系统和无状态的API。而传统的token方式需要在服务端存储相关信息,增加了服务端的负担。

4.查询操作:
在验证客户端发来的token信息时,传统token方式需要进行数据的查询操作,以验证token的有效性。而JWT方式则不需要,它只需在服务端使用密钥进行校验,无需查询数据库。

综上所述,JWT在安全性、扩展性、无状态性和减少服务端负担方面相对于传统的token方式具有显著的优势。
然而,具体选择哪种方式取决于应用的需求和安全考虑。
在某些简单的认证场景中,传统的token方式可能仍然适用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1495880.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】队列 循环队列 双端队列——顺序队列+链式队列完整代码(创建、入队、出队)

2.队列 2.1 队列的定义 定义 只允许在一端进行插入,另一端删除的线性表。 特征:先进先出(First In First Out->FIFO) 重要术语:队头、队尾、空队列 2.2 队列的顺序存储 2.2.1 初始化 结构体 typedef struct{…

数字人民币钱包(二)

文章目录 前言一 什么是数字人民币钱包?二 怎么开通数字人民币钱包?三 数字人民币钱包有哪些?四 数字人民币钱包升级 前言 上篇文章梳理了什么是数字人民币,及其特征和相关概念,这篇文章来整理下数字人民币钱包。数字人…

TOMCAT多实例及调优

一、JVM相关理论 (一)JVM组成 1.JVM组成部分 类加载子系统: 使用Java语言编写.java Source Code文件,通过javac编译成.class Byte Code文件。class loader类加载器将所需所有类加载到内存,必要时将类实例化成实例 运行时数据区…

1908_Arm Cortex-M3的实现

1908_Arm Cortex-M3的实现 全部学习汇总: g_arm_cores: ARM内核的学习笔记 (gitee.com) 这是第一次看一份这样的手册,之前的MCU编程基本上就是专注于软件接口方面。而OS等方面的一些功能基本上都是用了现成的解决方案,因此也就没有过多的关注…

NXP iMX8MM Cortex-M4 核心 GPT Capture 测试

By Toradex秦海 1). 简介 NXP i.MX8 系列处理器均为异构多核架构 SoC,除了可以运行 Linux 等复杂操作系统的 Cortax-A 核心,还包含了可以运行实时操作系统比如 FreeRTOS 的 Cortex-M 核心,本文就演示通过 NXP i.MX8MM 处理器集成的 Cortex-…

基于Springboot+Layui餐厅点餐系统

一、项目背景 在互联网经济飞速发展的时代,网络化企业管理也在其带领下快速兴起,开发一款自主点餐系统会受到众多商家的青睐。现如今市场上的人力资源价格是非常高昂的,一款自主点餐系统可以减少餐厅的人力开销,将服务员从繁忙的…

建立自己的富足金字塔

本文的理论参考: 1、《金字塔原理》,可以简述为:上下层互为支撑的结构化表达,通常为1-3-9结构;完全穷举、互不交叉,或不重不漏MECE的分门分类;真实有效,真知灼见。 2、《金线》在金字…

贷齐乐错误的waf引起的SQL注入漏洞复现

君衍. 一、环境介绍1、第一道WAF2、第二道WAF 二、环境部署1、模拟源码2、连接数据库源码3、数据库创建4、测试 三、源码分析1、模拟WAF2、注入思路3、PHP下划线特性4、完成假设 四、联合查询注入1、测试回显字段2、爆出库名3、爆出表名4、爆出表下的列名4、爆出flag 一、环境介…

AI大模型与小模型之间的“脱胎”与“反哺”(第五篇)

一、背景 AI大模型与小模型之间存在一种“脱胎”与“反哺”的关系,这种关系在AI技术的发展中起到了重要的作用。 首先,我们来理解一下“脱胎”的概念。在AI领域,大模型通常具有更大的参数量、更强的表达能力和更高的计算需求。这些大模型通…

第一个 Angular 项目 - 添加路由

第一个 Angular 项目 - 添加路由 前置项目是 第一个 Angular 项目 - 添加服务,之前的切换页面使用的是 ngIf 对渲染的组件进行判断,从而完成渲染。这一步的打算是添加路由,同时添加 edit recipe 的功能(同样通过路由实现) 用到的内容为&…

RabbitMQ 交换器

RabbitMQ 交换器 官方例子 http://www.rabbitmq.com/getstarted.html direct 如上图所示,两个队列绑定到了direct交换器上,第一个队列绑定的 binding key 为 orange ,第二个队列有两个绑定,分别是 black 和 green 。 如上图所示…

vue+element模仿实现云码自动验证码识别平台官网

一、项目介绍 项目使用传统vue项目结构实现,前端采用element实现。 element官网:Element - The worlds most popular Vue UI framework 云码官网地址:云码-自动验证码识别平台_验证码识别API接口_免费验证码软件 项目截图,支持…

一键安装conda-batch脚本

conda的安装可以更简化些,即使用batch文件,具体步骤如下: 新建文本文档,并改后缀名为.bat 使用文本编辑器编辑,并输入内容如下 echo offSET MINICONDA_INSTALLER_PATHminiconda3_installer.exe SET MINICONDA_UR…

实现一个网页版的简易猜数字游戏

实现一个网页版的简易猜数字游戏 效果 代码截图 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><t…

基于Matlab实现免疫荧光图像中的区域定位算法

基于Matlab实现免疫荧光图像中的区域定位算法 免疫荧光法。以荧光染料为标记物,试纸条为载体,发生抗原抗体特异性反应,根据免疫复合物被激发的荧光强度对待测物进行定量分析[。该方法具有环境要求不高、操作简单快速、无污染且荧光染料丰富等优点。 常用于食品安全检测过程中…

Python实现选择排序算法

Python实现选择排序算法 以下是使用Python实现选择排序算法的示例代码&#xff1a; def selection_sort(arr):n len(arr)for i in range(n):min_index i# 找到未排序部分的最小元素的索引for j in range(i 1, n):if arr[j] < arr[min_index]:min_index j# 将最小元素与…

【BUG】cmd运行wmic提示‘wmic‘ 不是内部或外部命令

cmd运行wmic提示‘wmic‘ 不是内部或外部命令 解决办法 将C:\Windows\System32\wbem添加到系统环境变量

《系统架构设计师教程(第2版)》第6章-据库设计基础知识-01-数据库基本概念

文章目录 1. 概述1.1 基本概念1&#xff09;信息 (Information)2&#xff09;数据 (Data)3&#xff09;数据库 (DB)4&#xff09;数据库系统(DBS)5&#xff09;数据库管理系统&#xff08;DBMS&#xff09; 1.2 数据库技术的发展1.2.1 人工管理阶段1.2.2 文件系统阶段1&#xf…

SQL中如何添加数据

SQL中如何添加数据 一、SQL中如何添加数据&#xff08;方法汇总&#xff09;二、SQL中如何添加数据&#xff08;方法详细解说&#xff09;1. 使用SQL脚本&#xff08;推荐&#xff09;1.1 在表中插入1.1.1 **第一种形式**1.1.2 **第二种形式**SQL INSERT INTO 语法示例SQL INSE…

代码学习记录10

随想录日记part10 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.03.03 主要内容&#xff1a;今天的主要内容是深入了解数据结构中栈和队列&#xff0c;并通过三个 l e e t c o d e leetcode leetcode 题目深化认识。 20. 有效的括号1047. 删除字符串中的所有…