互联网用户登录模式变迁史(二)
互联网用户登录模式变迁史(二)
我们先看一下现实中的例子,出去旅游(预计 3 天),肯定要订酒店,我们出示订单和手机号,酒店前台验证通过后,就可以给我们房卡,但是,房卡是有时间期限的(3 天),3 天内,我们回房间是不用再去前台登记了,直接进入房间。但是过了 3 天,这个房卡就失效了,除非我们继续和酒店续签。这和我们要说的 Oauth2.0 很相似。
这个案例里面有 3 个角色:
- 我(自己) 用户
- 酒店前台 授权中心
- 房间 资源
下面我们看一下 Oauth2.0 的运行流程,如下
- A—客户端向认证授权服务器请求 Access Token。
- B—授权服务器验证通过,签发 Access Token 过期属性等,还有 Refresh Token。
- C—携带 Access Token 访问资源服务器。
- D—资源服务器验证 Access Token,通过后,返回请求内容。
- E—执行 C 和 D,如果验证不通过,则执行 F 步骤。
- G—当 Access Token 过期的时候,那么携带 Refresh Token。这样无需用户再次登录。
- 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 是在服务器端发出的,然后对客户端进行身份验证。
用户想要登录,用户要授权操作,需要点击“使用 Oauth 登录”按钮,客户端将生成并向授权服务器发送登录请求。
用户被重定向到授权服务器。发送一个 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: 这是可选参数,登录过程后按原样返回给客户端,用于检查客户端应用程序信息。
请求验证
Authorization Server必须验证所有请求参数:
- client_id 是否存在这个客户端 ID?是否允许这个客户端执行此请求?
- redirect_uri 客户端是否可以使用这个重定向 URI?此重定向 URI 是否与此客户端关联?
- response_type 客户端是否允许使用这个响应类型?
- scope 是否允许客户端使用这些授权?
这些验证,都是授权服务器必须事先注册所有将访问的客户端。
登录表格
授权服务器显示登录表单,用户输入用户名和密码。(第 5 步)
验证数据是否正确(第 6 步)
使用授权码重定向到客户端
授权服务器生成一个授权码(authorization_code)并将其发送到客户端,发送到请求中指定的 URI。
8 和 9 授权码验证。
客户端必须调用授权服务器来验证接收到的 code,参数
**code ** 授权码
client_id 客户端 ID
client_secret 客户端密码,这个必须保存在安全的地方(通常保存在服务器后端)
授权服务器执行上述所有验证,检查授权是否完整、未更改、未过期操作。
客户端收到 access_token
授权服务器创建一个 access_token 并返回给客户端,有许多类型的令牌,它们具有到期日期并且可以刷新。通常,与令牌一起返回一些更多信息:
token_type 最著名的一种是 Bearer,代表授予对该令牌的持有者的访问权限。
expires_in 令牌的持续时间
refresh_token 另一个令牌,用于在 access_token 过期时更新它。
客户端使用 access_token
现在客户端已经获取了 access_token,可以访问资源服务器了。通常是 Rest Api,使用 HTTP Header Authorization 将 token_type 与 access_token 连接起来。
1
Authorization: Bearer iyMhbGciOiJABzI1NiIsInR5cCI6IkpXBGU
12 和 13 令牌验证
当资源服务器收到请求时,必须检查令牌是否存在和完整性。令牌验证可以是资源服务器自己也可以调用 Authorization Server。
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 | POST /token |
4.密码模式
这个模式是用在同一家公司出品的不同 App,用户在客户端输入用户名和密码,而不是在 Authorization Server 中。
这个请求的参数是:
- username 用户名
- password 密码
- client_id
- client_secret
- grant_type:
password
1 | POST /token |
添加微信 | 公众号更多内容 |
---|---|
![]() |
![]() |