认证是一个在用户或者设备在访问一个受限的系统时,鉴定用户凭据的过程,即确认"你是谁"的问题。最常见的认证用户的方式是通过用户名和密码的形式进行校验,目前存在多种校验方式,本文将对其进行一个简单的对比,使得大家能够有一个较为完整的了解。
Basic 认证
基本身份验证内置于 HTTP 协议中,是最基本的身份验证形式。它使用 HTTP 标头,以便在向服务器发出请求时提供用户名和密码
"Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" your-website.com
用户名和密码不加密。相反,用户名和密码会用:符号连接起来,形成一个字符串:username:password。然后使用 base64 对该字符串进行编码。这种方法是无状态的,因此客户端必须在每次请求时提供凭据。它适用于不需要持续会话的 API 调用和简单的身份验证工作流。
工作流
- 未经身份验证的客户端请求受限资源
- HTTP 401 未认证会返回一个值为 Basic 的 WWW-Authenticate 标头。
- WWW-Authenticate:Basic 头信息会使浏览器弹框显示用户名和密码,供用户输入凭据。
- 输入凭据后,每次请求都会在标头中发送凭据:Authorization:Basic dcdvcmQ=
优势
- 由于操作不多,使用这种方法认证速度更快。
- 易于实施。
- 所有主流浏览器都支持。
劣势
- Base64 与加密不同。它只是表示数据的另一种方式。base64 编码的字符串很容易被解码,因为它是以纯文本发送的。这种特性会导致多种类型的攻击。因此,HTTPS/SSL 是绝对必要的。
- 每次请求都必须发送凭证。
- 用户只能通过重写无效的凭据才能注销。
Diget 认证
HTTP 摘要验证(或摘要访问验证)是 HTTP Basic验证的一种更安全的形式。主要区别在于密码是以 MD5 散列形式发送,而不是以纯文本形式发送,因此比基本认证更安全。
工作流
- 未经身份验证的客户端请求受限资源
- 服务器生成一个称为 nonce 的随机值,并发回一个 HTTP 401 未授权状态和一个 WWW-Authenticate 标头,该标头的值与 nonce 一起为 Digest: WWW-Authenticate: Digest nonce="44f0437004157342f50f935906ad46fc"
- WWW-Authenticate: Diget标头会使浏览器显示用户名和密码提示
- 输入凭据后,密码将被散列,然后在每次请求时连同 nonce 一起在标头中发送: Authorization:Digest username="username",nonce="16e30069e45a7f47b4e2606aeeb7ab62", response="89549b93e13d438cd0946c6d93321c52"
- 有了用户名,服务器就能获取密码,将其与nonce一起散列,然后验证散列是否相同.
优势
- 由于密码不会以纯文本形式发送,因此比基本认证更安全。
- 易于实施。
- 所有主流浏览器都支持。
劣势
- 每次请求都必须发送凭据(与Basic的方式一样)。
- 用户只能通过重写无效的凭据才能注销。
- 与Basic认证相比,密码在服务器上的安全性较低,因为不能使用 bcrypt。
- 易受中间人攻击。
基于 Session 的认证
使用基于会话的验证(或会话 cookie 验证或基于 cookie 的验证)时,用户的状态存储在服务器上。它不要求用户在每次请求时提供用户名或密码。相反,在登录后,服务器会验证凭据。如果有效,服务器会生成一个会话,将其存储在会话存储区中,然后将会话 ID 发回给浏览器。浏览器会将会话 ID 存储为 Cookie,在向服务器发出请求时随时发送。
基于会话的身份验证是有状态的。每次客户端请求服务器时,服务器都必须在内存中找到会话,以便将会话 ID 与相关用户联系起来。
工作流
优势
- 后续登录更快,因为不需要凭据。
- 改善用户体验。
- 相当容易实现。许多框架开箱即提供此功能。
劣势
- 它是有状态的。服务器会在后端跟踪每个会话。用于存储用户会话信息的会话存储需要在多个服务间共享,以实现身份验证。正因为如此,它不能很好地用于 RESTful 服务,因为 REST 是一种无状态协议。
- 即使不需要身份验证,每次请求也会发送 Cookie。
- 易受 CSRF 攻击
基于 Token 的认证
这种方法使用令牌而不是 cookie 来验证用户。用户使用有效凭证进行身份验证,服务器返回一个签名令牌。该令牌可用于后续请求。
最常用的令牌是 JSON 网络令牌(JWT),关于JWT的详细介绍,请查看JWT简介-CSDN博客
令牌无需保存在服务器端。只需使用其签名进行验证即可。近来,由于 RESTful API 和单页面应用程序(SPA)的兴起,令牌的采用率越来越高。
工作流
优势
- 它是无状态的。服务器不需要存储令牌,因为可以使用签名进行验证。由于不需要查找数据库,因此请求速度更快。
- 适用于需要验证多个服务的微服务架构。我们只需在每一端配置如何处理令牌和令牌密文。
劣势
- 根据客户端保存令牌的方式,它可能会导致 XSS(通过 localStorage)或 CSRF(通过 cookies)攻击。
- 令牌不能删除。它们只能过期。这就意味着,如果令牌被泄露,攻击者可以滥用令牌直到过期。因此,将令牌过期时间设置得很小很重要,比如 15 分钟。
- 刷新令牌需要设置为在到期时自动发放令牌。
- 删除令牌的一种方法是创建一个将令牌列入黑名单的数据库。这会增加微服务架构的额外开销,并引入状态。