搞不清楚现在项目的鉴权方法是哪一种?混淆,摸不清楚该做什么?今天的文章就是为了解决这个问题的(灵感来源于跟同事的知识分享会)

Basic Authentication

工作原理

  • 基本认证就是使用Base64编码的用户和密码,在HTTP头部进行身份验证
  • 客户端在请求的时候,会在header中添加Authentication,值为Basic Base64(username:password)

特点

  • 简单,前端后端都很简单,不用加密,不需要存储东西

    适用场景

  • 内部网络:适用于内部网络、测试环境等对安全性要求较低的场合。建议搭配IP白名单

    问题

  • 明文传输:Base64编码的用户名密码以明文形式传输,可以直接破解
  • 无状态:服务器并不会维护会话状态,客户端需要在每次请求的时候都发送用户名和密码

Cookie+session

工作原理

  • 客户端在登录时,服务器生成一个带有用户信息的session对象,并且将session对象的ID存在Cookie中
  • 后续请求中,浏览器会自动携带该Cookie的session ID,服务器根据session ID验证用户的身份

特点

  • Cookie方便,无需手动携带
  • 有状态,sessionID会保存在服务器端

    问题

  • 跨域问题:Cookie默认不支持跨域,可能会受到跨站请求伪造攻击。
  • CSRF攻击:由于浏览器会自动发送Cookie,可能会受到跨站请求伪造攻击。攻击者可能诱导用户点击链接或通过其他方式发起从用户浏览器向应用发起的恶意请求,由于请求会自动携带用户的Cookie,因此应用可能会误认为这些请求是用户自愿发起的。
  • 跨站脚本攻击(XSS):如果Web应用未能妥善处理用户输入,攻击者可以注入恶意脚本,窃取Cookie信息
  • 会话劫持:如果Session ID泄露,可能会被黑客劫持用户会话
  • 对非浏览器的环境不友好:Cookie的自动携带依赖于浏览器,否则需要自行维护

Header+Token

工作原理

  • 客户端在请求的时候,在header中添加Authentication,值为Bear {token},token是用户在登陆的时候,由服务器返回的。

特点

  • 无状态:后端不需要维护用户的对话状态,因为用户的身份信息&权限都包含在token中
  • 支持跨域:Token在请求的header中传递,因此很容易支持跨域请求

    JWT(JSON WEB TOKEN)

  • JWT是一种开放标准(RFC 7519),用于在网络应用之间安全传输信息
  • 由Header(头部)、payload(负载)、signature(签名)三部分组成,通过.来分割
    比如:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header(头部)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
/*base解码*/
{
  "alg": "HS256",
  "typ": "JWT"
}

/**
alg是必需的,指定了签名算法
typ可以省略,通常是JWT,其它有JWE,JWS等
*/
Payload(负载)
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
/*base解码*/
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

/**
不要存放敏感信息
*/
Signature(签名)
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
/*base解码*/
❌ ❌ ❌
/**
Signature⽤于确保JWT的完整性和防⽌篡改。
其实就是使⽤header中的alg字段指定的算法,结合预⽣成的密钥,对`base64(header).base64(payload)`进⾏计算
*/

经过上面的解析,我们不难看出,防伪造的关键在于预生成的秘钥

在验证JWT的时候,服务器会根据Header中指定的算法,使用预生成的秘钥对JWT的Header和Payload进行签名计算,然后将计算得到的签名与JWT的Signature进行比较,验证JWT的完整性

特点

  • 无状态:JWT是无状态的,服务器不需要在后端存储会话信息,减轻服务器负担
  • 可拓展:负载中可以存储自定义的用户信息,适用不同场景,灵活使用
  • 安全性:JWT的签名可以防止数据篡改,只要秘钥安全,那么信息就是可信任的

问题

  • Token长度:JWT包含了头部和负载的base64编码,以及签名,可能会导致较大的Token大小,增加了网络传输的开销
  • 过期时间管理:JWT一旦签发,其有效期一般来说是固定的,如果需要即时撤销访问权限,需要额外实现Token的撤销机制
  • 秘钥管理:安全性依赖于秘钥的保护和轮换,需要合理管理秘钥

OAUTH 2.0

  • Access Token(访问令牌):

    • 用于访问受保护资源的令牌
    • 可以是普通的长字符串,也可以是JWT
    • 有效期比较短
  • Refresh Token(刷新令牌)

    • 用于获取新的Access Token的令牌
    • 通常是普通长字符串
    • 有效期较长
    • 当Access Token生效或者过期的时候,客户端可以使用Refresh Token向授权服务器发起请求新的Access Token(同时也会请求新的Refresh Token),无需再请求用户授权或者登录
    • Refresh Token的存在使得Access Token的有效期可以缩短,减少Access Token在网络传输过程中被截获的风险。反过来说:如果Refresh Token被泄露,那么攻击者可以使用它来不断获取新的Access Token,从而长时间访问受保护的资源。由于Refresh Token通常有较长的有效期,这就给攻击者留出了较大的操作空间。因此,尽管使用Refresh Token可以减少Access Token泄露的风险,但一旦Refresh Token本身被泄露,后果可能更为严重。
  • ID Token(身份令牌)

    • ID Token是OpenID Connect协议的概念,用于向客户端传递有关用户身份的信息
    • 是一个JSON WEB Token(JWT),包含了用户的id,name等信息
    • 主要用于客户端对用户进行身份验证,以及获取有关用户的信息,比如显示用户头像,姓名等等
    • 通常在认证成功之后,随着Access Token一起返回给客户端

特点

  • 适用于不同的应用场景和授权需求,提供不同的授权类型选择

    使用场景

  • 前后端分离:提供了完整的授权方案
  • 第三方应用授权:允许第三方应用以用户身份访问用户授权的资源
  • 需要做出权限区分:可以根据需要给不同的Access Token不同的权限

    问题

  • 较为复杂:需要管理各种Token
  • 刷新令牌管理:与我上面说的一样,一旦刷新Token被盗用,后果就会严重很多,需要对刷新令牌进行合理的管理和保护,防止被盗用
  • 令牌过期管理:需要合理设置令牌的过期时间,确保及时更新令牌
最后修改:2024 年 07 月 03 日
收款不要了,给孩子补充点点赞数吧