互联网用户登录模式变迁史(二)

我们先看一下现实中的例子,出去旅游(预计 3 天),肯定要订酒店,我们出示订单和手机号,酒店前台验证通过后,就可以给我们房卡,但是,房卡是有时间期限的(3 天),3 天内,我们回房间是不用再去前台登记了,直接进入房间。但是过了 3 天,这个房卡就失效了,除非我们继续和酒店续签。这和我们要说的 Oauth2.0 很相似。

这个案例里面有 3 个角色:

  1. 我(自己) 用户
  2. 酒店前台 授权中心
  3. 房间 资源

下面我们看一下 Oauth2.0 的运行流程,如下

oauth2

  1. A—客户端向认证授权服务器请求 Access Token。
  2. B—授权服务器验证通过,签发 Access Token 过期属性等,还有 Refresh Token。
  3. C—携带 Access Token 访问资源服务器。
  4. D—资源服务器验证 Access Token,通过后,返回请求内容。
  5. E—执行 C 和 D,如果验证不通过,则执行 F 步骤。
  6. G—当 Access Token 过期的时候,那么携带 Refresh Token。这样无需用户再次登录。
  7. H—如果执行 G 步骤,成功的话,那么就返回 Access Token。

授权模式

名词解释

User 想要被认证和访问受保护信息的人。

Client App 客户端应用程序(Web 或 App 或小程序)

Authorization Server(认证服务器) 执行身份验证和授权的组件,处理登录请求+用户身份验证+令牌生成+安全验证

Resource Server(资源服务器) 公开资源,可能是一个 Rest Api。Client App 获取 Access Token 后,会携带 access_token 来访问资源服务器。

1.授权码模式

授权码模式是最完整和最复杂的流程。登录过程分为两个阶段,确保更高的安全性。

颁发并用于获取access_token代码。在用户登录后发布到前端应用程序(在浏览器上或返回 Restful Api)。 access_token 是在服务器端发出的,然后对客户端进行身份验证。

授权码模式流程图

  1. 用户想要登录,用户要授权操作,需要点击“使用 Oauth 登录”按钮,客户端将生成并向授权服务器发送登录请求。

  2. 用户被重定向到授权服务器。发送一个 http 的 Get 的 Redirect 请求

    1
    https://the-authorization-server/token?client_id=[the_client_id]&redirect_uri=[a redirect uri]&response_type=code&scope=[list of scopes]&state=[some client parameter]
    • client_id:表示调用的应用程序

    • redirect_uri:用户登录后,授权服务器将发送(重定向)授权码的 URL

    • response_type: 对于授权码模式,这个参数就是 code

    • scope:应用程序访问用户的许可列表。当客户端访问资源服务器时,这将很有用,这将决定是否允许或拒绝访问。例如: read_post、write_post,如果客户端获取 access_token 后,再次调用 /account-id/freinds 范围的 API,就会被拒绝访问。

    • state: 这是可选参数,登录过程后按原样返回给客户端,用于检查客户端应用程序信息。

  3. 请求验证

    Authorization Server必须验证所有请求参数:

    • client_id 是否存在这个客户端 ID?是否允许这个客户端执行此请求?
    • redirect_uri 客户端是否可以使用这个重定向 URI?此重定向 URI 是否与此客户端关联?
    • response_type 客户端是否允许使用这个响应类型?
    • scope 是否允许客户端使用这些授权?

    这些验证,都是授权服务器必须事先注册所有将访问的客户端。

  4. 登录表格

    授权服务器显示登录表单,用户输入用户名和密码。(第 5 步)

    验证数据是否正确(第 6 步)

  5. 使用授权码重定向到客户端

    授权服务器生成一个授权码(authorization_code)并将其发送到客户端,发送到请求中指定的 URI。

  6. 8 和 9 授权码验证。

    客户端必须调用授权服务器来验证接收到的 code,参数

    **code ** 授权码

    client_id 客户端 ID

    client_secret 客户端密码,这个必须保存在安全的地方(通常保存在服务器后端)

    授权服务器执行上述所有验证,检查授权是否完整、未更改、未过期操作。

  7. 客户端收到 access_token

    授权服务器创建一个 access_token 并返回给客户端,有许多类型的令牌,它们具有到期日期并且可以刷新。通常,与令牌一起返回一些更多信息:

    • token_type 最著名的一种是 Bearer,代表授予对该令牌的持有者的访问权限。

    • expires_in 令牌的持续时间

    • refresh_token 另一个令牌,用于在 access_token 过期时更新它。

  8. 客户端使用 access_token

    现在客户端已经获取了 access_token,可以访问资源服务器了。通常是 Rest Api,使用 HTTP Header Authorization 将 token_type 与 access_token 连接起来。

    1
    Authorization: Bearer iyMhbGciOiJABzI1NiIsInR5cCI6IkpXBGU
  9. 12 和 13 令牌验证

    当资源服务器收到请求时,必须检查令牌是否存在和完整性。令牌验证可以是资源服务器自己也可以调用 Authorization Server。

  10. 14 和 15 访问和显示受保护的资源

    一旦资源服务器验证成功,就会把资源返回给客户端,最终显示给用户。

2.隐式模式

简化模式流程图

此流程与 Authentication Code一非常相似,但access_token 在用户登录后立即以隐式方式返回给客户端**。您在单页应用程序和纯 Javascript 应用程序中使用此流程,在这些应用程序中无法对 client_secret 保密。涉及的参与者与之前的流程相同。

第一个区别是在初始重定向到授权服务器期间,参数response_type的值token不是code. 这意味着来自服务器的响应类型将(立即)是access_token,而不是authorization_code

通过这种方式,您可以为客户端执行更少的步骤,但安全性也会降低,因为整个流程都是在浏览器(或一般而言的用户代理)上执行的,包括令牌。授权代码流中,令牌来自服务器到服务器的调用,因此更难以拦截或操纵它。

3.客户端模式

客户端模式流程图

上述流程之间的主要区别在于,在这一流程中没有用户交互。应用程序直接执行身份验证请求。

这意味着应用程序不能代表用户执行任何操作,而只能代表它自己。

此流程不会发生在浏览器上,而是发生在服务器上。没有重定向,而是HTTP POST执行了一个调用,请求的参数为:

  • client_id
  • client_secret
  • 授予类型:client_credentials
1
2
3
4
5
POST /token

&client_id=面向加薪学习
&client_secret=xxxxxxx
&grant_type=client_credentials

4.密码模式

密码模式流程图

这个模式是用在同一家公司出品的不同 App,用户在客户端输入用户名和密码,而不是在 Authorization Server 中。

这个请求的参数是:

  • username 用户名
  • password 密码
  • client_id
  • client_secret
  • grant_typepassword
1
2
3
4
5
6
7
POST /token

grant_type=password
&username=www.go-edu.cn
&password=TheUserPassword
&client_id=client-app
&client_secret=xxxxxxx

添加微信 公众号更多内容
wechat gzh