Skip to content

登录鉴权

登录方式

  • 用户名+密码登录。最原始的登录方式,实现简单。用户在注册时提供一个不重复的唯一标识,作为用户的区分,如用户可以取一个与其他用户不重复的用户名,或者提供邮箱地址、手机号码等身份标识。同时,用户指定密码,用于用户的登录。后端生成账户,使用 hash 值保存密码。
  • 验证码登录。登录时,由服务端向用户的第三方联系方式发送验证码,用户使用第三方联系方式并查收验证码,用户输入验证码进行登录。
  • 双因素验证登录。同时使用密码登录和验证码登录,两种方式都通过了,才能登录。为了提高登录操作的安全性,防止密码泄露。

登录状态保持

由于 http 协议的无状态性,每次 http 请求均需要进行验证,为了减少验证的次数,提高用户的体验,需要未登录的用户颁发授权令牌,利用浏览器的 cookie 机制,cookie 可以在每次请求时携带一部分信息,由 cookie 携带用户令牌,免去用户在登录授权之后打重复的登录操作。具体实现的时候,可以分成 session 实现和 jwt 实现。

  • session。用户登录之后,对用户发放 sessionID,在服务器端记录了 sessionID 的登录情况,在之后的请求中,校验 cookies 中的 sessionID 是否合法登录,从而来判断是否放行请求。该方法对服务器的存储压力较大,并且如果进行分布式架构的话需要使用 redis 等存储 sessionID,从而实现在服务器集群中共享登录状态。
  • jwt。用户登录之后,对用户发放 jwt 令牌。令牌由三部分 base64 的编码的信息构成,使用.进行分隔,<header>.<payload>.<sign>。其中 header 记录了 jwt 的一些元信息,payload 代表了被签名的信息内容,sign 代表签名,签名是对 header 和 payload 的签名,使用一定的算法和秘钥进行签名,秘钥是服务端的机密文件。用户后续请求时,服务端检查令牌,没有令牌则拒绝,如果有令牌则校验令牌,使用同样的算法和秘钥对 header 和 payload 的内容进行签名计算,比对用户提供的令牌中的 sign 和现场计算的 sign 是否相同,如果相同则放行,不同则拒绝。该方式,使用了时间换空间的思路,将用户的登录状态存储在用户的机器上,减轻了服务端的存储压力,并且使得服务端无需管理登录状态。

单点登录架构

在大型的服务项目中,将一组用户账户信息共同的服务的登录服务托管到同一个服务器上,从而实现一个账户、多端登录,优化用户体验,同时将服务端的任务进行明确分工。在用户登录时访问统一的登录服务器,由登录服务器统一发放 token,并且在后续的校验中,可以采用不同的方式进行实现,例如,在使用 nginx 对需要权限控制的请求代理到 gateway 集群,gateway 集群对令牌进行校验,然后将请求传递到相应的上游服务,或者拒绝服务。

三方登录

在构建服务时,使用一些现有的第三发机构提供的服务,代理用户在第三方服务上进行操作。这是一个获取授权的过程,第三方授权我们代替用户对其在第三方上的资源进行管理和操作。具体的操作需要查看第三方服务提供商的开发者文档。经常使用的三方登录技术为 OAuth2。它有四种主要的授权方式(授权码、简化模式、密码模式、客户端凭据模式),其中最常用于第三方登录的是授权码模式(Authorization Code Grant)。

授权码模式

  1. 用户点击第三方登录按钮。例如,用户在我们的应用上点击“用 Google 登录”等按钮。
  2. 请求授权码。用户被重定向到第三方提供者的授权页面(如 Google 的登录页面)。用户登录并同意授权我的应用访问其信息。
  3. 获取授权码。第三方提供者将用户重定向回我的应用,并带上一个授权码。
  4. 交换授权码为访问令牌。我的应用用授权码向第三方提供者的授权服务器请求访问令牌,最后获得访问令牌。
  5. 使用访问令牌访问资源。我的应用使用访问令牌从第三方提供者的 API 获取用户信息。

简化模式

  1. 用户通过我的客户端向授权服务器请求令牌。
  2. 用户被重定向到授权服务器进行身份验证。
  3. 如果验证通过,授权服务器直接返回访问令牌。

密码模式

  1. 用户告诉我们用户在第三方服务的用户名和密码。
  2. 我们用这些凭据向授权服务器请求访问令牌。
  3. 授权服务器验证凭据并返回访问令牌。

客户端凭据模式

  1. 客户端用自身的客户端 ID 和密钥向授权服务器请求访问令牌。
  2. 授权服务器验证凭据并返回访问令牌。