一文搞懂用户认证方案怎么做

admin2024-04-03  5

session cookie

一般网站用户认证不外乎以下步骤:

1、用户向服务器发送用户名和密码。

2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。

3、服务器向用户返回一个 session_id,写入用户的 Cookie。

4、用户随后的每一次请求,都会通过 Cookie,将 session_id 传回服务器。

5、服务器收到 session_id,找到前期保存的数据,由此得知用户的身份。

以上单机版基本没问题,但是分布式系统中涉及到 session 共享问题,比如 项目部署在serviceA 和 serviceB。用户登录后 sessionId 存在 serviceA 内存中,这个时候如果 a 挂掉了(lb 打到 b 服务器也有可能),你再请求服务器 b,发现sessionId不存在,直接让你重新登录了。

首先,问题的根源出在sessionId无法共享上,想要把sessionId共享,一个简单的思路就是把sessionId保存到数据库中(这里选择redis),这样验证的时候就不再从当前服务器获取sessionId了,而改为了从redis中获取。

Token+缓存

下面是使用 Token(相当于 session) 和 Redis 进行用户认证的基本流程:

  1. 用户登录:

    • 用户提供用户名和密码进行登录。
    • 服务器验证用户提供的凭据是否正确。
  2. 生成 Token:

    • 如果用户提供的凭据正确,服务器会生成一个 Token。
    • Token 包含用户身份信息和其他必要的元数据。
  3. 存储 Token 到 Redis:

    • 服务器将生成的 Token 存储到 Redis 数据库中。
    • Token 作为键值对的形式存储,键通常是用户标识符,值是 Token。
  4. 将 Token 发送给客户端:

    • 服务器将生成的 Token 发送给客户端,通常是通过 HTTP 响应的方式发送给客户端。
  5. 客户端存储 Token:

    • 客户端通常会将 Token 存储在本地,如 localStorage、sessionStorage 或者内存中。
  6. 用户请求受保护资源:

    • 当用户访问受保护的资源时,客户端会在请求中包含 Token。通常,Token 被添加到 HTTP 请求的头部,如 Authorization 头部中。
  7. 验证 Token:

    • 服务器接收到请求后,会从请求中提取 Token。
    • 服务器验证 Token 的签名和有效性,以确保它是有效的且没有被篡改的。
  8. 从 Redis 中检索 Token:

    • 如果 Token 有效,服务器会从 Redis 数据库中检索 Token,并验证其有效性和关联的用户身份信息。
  9. 授权访问:

    • 如果 Token 有效,并且与用户的身份信息匹配,服务器将授权用户访问请求的资源。
  10. 定期更新 Token:

    • 在 Token 的有效期内,客户端可以通过定期更新 Token 来保持用户的会话持续有效。
    • 客户端可以使用 Refresh Token 或者其他方式来获取新的 Token。
  11. 用户登出:

    • 用户可以通过退出登录来终止当前会话,服务器会将 Token 从 Redis 中删除,同时客户端也应该删除存储的 Token。

通过以上流程,使用 Token 和 Redis 进行用户认证能够有效地保护用户的身份信息,并且能够实现灵活的会话管理和访问控制。

JWT

以上都是维护有状态的情况,比如需要记录用户登录、在线、权限等。加入内网环境或者邮件取消等无状态场景可以选用 JWT模式。

JWT(JSON Web Token)是一种用于身份验证和信息传递的开放标准(RFC 7519),通常用于跨域认证。下面是使用 JWT 进行用户认证的基本流程:

  1. 用户登录:

    • 用户提供用户名和密码进行登录。
    • 服务器验证用户提供的凭据是否正确。
  2. 生成 JWT:

    • 如果用户提供的凭据正确,服务器会生成一个 JWT。
    • JWT 包含用户身份信息和其他必要的元数据,如过期时间等。
  3. 将 JWT 发送给客户端:

    • 服务器将生成的 JWT 发送给客户端,通常是通过 HTTP 响应的方式发送给客户端。
  4. 客户端存储 JWT:

    • 客户端通常会将 JWT 存储在本地,如 localStorage、sessionStorage 或者内存中。
  5. 用户请求受保护资源:

    • 当用户访问受保护的资源时,客户端会在请求中包含 JWT。通常,JWT 被添加到 HTTP 请求的头部,如 Authorization 头部中。
  6. 验证 JWT:

    • 服务器接收到请求后,会从请求中提取 JWT。
    • 服务器验证 JWT 的签名和有效性,以确保它是有效的且没有被篡改的。
  7. 解析 JWT:

    • 如果 JWT 有效,服务器会解析 JWT,提取其中的用户身份信息和其他元数据。
  8. 授权访问:

    • 如果 JWT 有效,并且包含的用户身份信息是合法的,服务器将授权用户访问请求的资源。
  9. 定期更新 JWT:

    • 在 JWT 的有效期内,客户端可以通过定期更新 JWT 来保持用户的会话持续有效。
    • 客户端可以使用 Refresh Token 或者其他方式来获取新的 JWT。
  10. 用户登出:

    • 用户可以通过退出登录来终止当前会话,此时客户端应该删除存储的 JWT。

总结

对比token+redis 和jwt:

1. 去中心化的JWT token

  • 优点:

    1. 去中心化,便于分布式系统使用
    2. 基本信息可以直接放在token中。 username,nickname,role
    3. 功能权限较少的话,可以直接放在token中。用bit位表示用户所具有的功能权限
  • 缺点:服务端不能主动让token失效

    2. 中心化的 redis token / memory session等

  • 优点:服务端可以主动让token失效

  • 缺点:

    1. 依赖内存或redis存储。
    2. 分布式系统的话,需要redis查询/接口调用增加系统复杂性。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!