文章目录
- OAuth2.0 知识点梳理
- 一、四种角色
- 二、四种模式的概述
- 三、四种模式的图解
OAuth2.0 知识点梳理
一、四种角色
为了能够更好的理解本文中后续的内容,这里我先说下,OAuth2.0 中相关的四种角色,如下:
- 资源拥有者
- 资源服务
- 客户端
- 认证服务
以上四种角色到底都是干什么的呢?这里直接用个例子来说明下:
某SAAS平台要实现基于微信账号的登录(第三方登录),该平台(客户端)从微信认证服务(认证服务)得到某用户(资源拥有者)的授权从微信(资源服务)上获取该用户的信息(资源)。
二、四种模式的概述
OAuth2.0 提供了四种授权(获取令牌)方式来应对不同的使用场景,如下:
-
授权码模式
特点: 四种模式中最安全,也最复杂的一种模式。
场景: 客户端通过认证服务得到用户授权继而调用资源服务,例如:客户端通过微信认证服务得到用户的授权继而访问到用户在微信中的个人信息。
-
密码模式
特点: 用户的用户名和密码直接暴露给客户端。
场景: 用户通过客户端提供的页面进行登录(输入用户名和密码),然后再由客户端调用认证服务进行认证授权。由于登录页面是客户端提供的,所以用户的用户名和密码将会暴露给客户端。安全起见,密码模式多见于自己开发的应用,例如:我司开发了某个应用对接了自己开发的认证服务和资源服务。
-
客户端模式
特点: 针对客户端(例如:某系统、某APP…)层面进行授权,而非基于用户授权的场景,认证服务仅校验客户端的身份。
场景: 客户端作为一个我方完全信任的存在,调用我方提供的资源服务,例如:某某平台要通过我方开发的OpenAPI获取我方的组织架构信息。
-
简化模式
特点: 不需要与客户端应用的服务端进行交互,没有校验 client_secret。
场景: 用于仅有前端页面,没有后端服务的客户端应用
基于以上四种模式是否与用户相关,为了便于理解,我又将这四个模式分为两大类:
- 用户认证(与用户相关): 授权模式,密码模式,简化模式。
- 客户端认证(与用户无关): 客户端模式。
三、四种模式的图解
首先我们要为客户端分配一对儿 client_id 和 client_secret,并指定该客户端可访问的资源(通过 scope,可以将 scope 作为资源的标签来理解)
-
客户端模式
A. 客户端的 authorized_grant_types 中必须包括 client_credentials,也就是客户端需要支持客户端模式。
B. 客户端携带 client_id 和 client_secret 访问认证服务的 oauth/token 以此获得 access_token。
C. 客户端携带 access_token 去资源服务那里访问有权访问的资源。获取 access_token 的请求:
http://oauth.cab5.com/oauth/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&scope=SCOPE
参数 说明 grant_type 授权类型,固定值:client_credentials,表示当前获取access_token的请求为客户端模式 client_id 客户端标识 client_secret 客户端秘钥 scope 客户端权限 -
密码模式
A. 客户端的 authorized_grant_types 中必须包括 password,也就是客户端需要支持密码模式。
B. 用户通过客户端提供的页面属于用户名和密码。
C. 客户端携带用户输入的用户名和密码,以及client_id 和 client_secret 访问认证服务的 oauth/token 以此获得 access_token。
D. 客户端携带 access_token 去资源服务那里获取用户信息。获取 access_token 的请求:
http://oauth.cab5.com/oauth/token?grant_type=password&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&username=USERNAME&password=PASSWORD&scope=SCOPE
参数 说明 grant_type 授权类型,固定值:password,表示当前获取access_token的请求为密码模式 username 用户名 password 用户密码 client_id 客户端标识 client_secret 客户端秘钥 scope 客户端权限 -
授权码模式
A. 客户端的 authorized_grant_types 中必须包括 authorization_code,也就是客户端需要支持授权码模式。
B. 用户通过浏览器首次访问客户端,客户端判断当前用户需进行认证授权(即需要登录),则重定向到认证服务的认证授权页面。
C. 用户在认证服务的认证授权页面上输入用户名和密码,并提交到认证服务进行验证,验证通过后,认证服务生成对应的授权码,然后携带该授权码重定向到客户端。
D. 客户端拿到授权码后,携带授权码、client_id、client_secret 访问认证服务的 oauth/token 以此获得 access_token。
E. 客户端携带 access_token 去资源服务那里获取用户信息。授权认证页面的请求:
http://oauth.cab5.com/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=SCOPE
参数 说明 response_type 固定值:code,表示当前的请求为授权码模式 client_id 客户端标识 redirect_uri 授权码生成后会重定向到该地址上,并携带code(授权码) scope 客户端权限 获取 access_token 的请求:
http://oauth.cab5.com/oauth/token?grant_type=authorization_code&code=CODE&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&scope=SCOPE
参数 说明 grant_type 授权类型,固定值:authorization_code,表示当前获取access_token的请求为授权码模式 code 授权码,只能使用一次,使用完了(即获取过一次access_token了)即刻作废,需要重新申请 client_id 客户端标识 client_secret 客户端秘钥 scope 客户端权限 -
简化模式
A. 客户端的 authorized_grant_types 中必须包括 implicit,也就是客户端需要支持简化模式。
B. 用户通过浏览器跳转到认证服务的认证授权页面。
C. 用户在认证服务的认证授权页面上输入用户名和密码,并提交到认证服务进行验证,验证通过后,认证服务生成对应的 access_token,然后携带该 access_toekn 重定向到客户端,形如:https://xx.xxx.com/#access_token=ACCESS_TOKEN,这里的https://xx.xxx.com为REDIRECT_URI。授权认证页面的请求:
http://oauth.cab5.com/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=SCOPE
参数 说明 response_type 固定值:token,表示当前的请求为简化模式 client_id 客户端标识 redirect_uri access_token 生成后会重定向到该地址上,并携带access_token scope 客户端权限 所谓简化模式其实就是对授权模式的简化,用户认证授权后直接生成 access_token,无需客户端再通过授权码换取access_token,整个过程无需提供 client_secret。