# 使用 OAuth 授权

'Node.JS Demo 源码:https://github.com/Authing/oauth-demo'

# 使用 authorization-code 模式

以下流程图列举了一种使用 OAuth 协议授权码模式的方式。

授权码模式流程图

# 1. 请求授权

首先需要请求以下链接来获取 authorization_code

https://sso.authing.cn/authorize?app_id=5c7253efe21948de32723725&state=123456lkjljkf3&response_type=code&redirect_uri=https%3A%2F%2Fauthing.cn&scope=user

此链接会重定向到 Authing 提供的认证授权页面,此时用户需要输入他的用户名密码或社会化登录手段进行登录。

你可以前往这个网址体验:https://sample-sso.authing.cn/login

请使用浏览器访问此链接!

# 参数说明

参数 说明
app_id 必须,创建 OAuth 应用后详情中的 App ID
response_type 必须,授权的类型,在 authorization_code 模式 中值必须为 "code"
redirect_uri 必须,授权成功后的回调地址,必须与控制台 OAuth 应用配置的 URL 一致,需要经过 urlencoded 编码
state 一段随机字符串,主要用于防止跨站请求伪造攻击,它将原封不动地在 redirect_uri 中返回
scope 允许的授权的范围,暂时没有实现此字段的相关功能,可不传

# 2. 重定向并获取 access_token

经过上一步之后,用户将会跳转到 Authing 提供的认证授权页面:

当授权成功后,用户将会被重定向到以下链接:

{redirect_uri}?code=8cce9189ee40f6f8874a9d4618a2996ece7dd737&state=123456lkjljkf3

链接中带有 GET 请求参数 codestate。在 redirect_uri 的请求处理中,你应该检查 state 参数是否与你请求时一致,这样能确保请求不是来自第三方应用。然后,你应该使用 POST 请求https://sso.authing.cn/token 来获取 access_token,需要携带以下参数

参数 说明
app_id/client_id 必须,创建 OAuth 应用后详情中的 App ID
app_secret/client_secret 必须,创建 OAuth 应用后详情中的 App Secret
code 必须,我们返回的 code
redirect_uri 必须,授权成功后的回调地址,必须与控制台 OAuth 应用配置的 URL 一致,需要经过 urlencoded 编码
grant_type 必须,授权类型,在 authorization_code 模式中必须为 "authorization_code"

同时 Content-Typeapplication/x-www-form-urlencoded

例如:

curl --request POST \
  --url https://sso.authing.cn/token \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data 'app_id=<APP_ID>&app_secret=<APP_SECRET>&grant_type=authorization_code&code=<CODE>&redirect_uri=<REDIRECT_URI>'    

返回:

{
  "access_token":"4331396b953d3de3bcf74c564455323d0989a9a0",
  "token_type":"Bearer",
  "expires_in":3599, // token 有效时间
  "refresh_token":"017888c6722e3433f3840a6708d9b79c23b310b8" // 可用此 token 来重新获取新的 token 而无需重新授权
}

# 3. 使用 access_token 请求 userInfo

GET https://users.authing.cn/oauth/user/userinfo?access_token=...

或作为 Authoriztion 头:

Authorization: Bearer { access_token }

# 4. 刷新 access_token

access_token 的有效时间只有 1 小时,refresh_token 的有效时间为 2 周,所以在申请 access_token 一小时以后,可通过 POST 请求https://sso.authing.cn/token 来重新获取 access_token,需要携带以下参数:

参数 说明
app_id 必须,创建 OAuth 应用后详情中的 App ID
app_secret 必须,创建 OAuth 应用后详情中的 App Secret
refresh_token 必须,之前获取 access_token 时返回的 refresh_token
grant_type 必须,授权类型,在刷新 token 时必须为 "refresh_token"

返回的数据与第二步一样。

# implicit 模式

authorization_code 不同,implicit 模式 直接返回 access_token,少了验证 authorization_code 的步骤,且不能刷新 access_token

下面 implicit 模式时序图中红框部分是与授权码模式不同的地方。

implicit 模式

# 1. 发起授权

https://sso.authing.cn/authorize?app_id=5c7253efe21948de32723725&state=123456lkjljkf3&response_type=token&redirect_uri=https%3A%2F%2Fauthing.cn&scope=user

通过请求以上链接可直接获取 access_token

参数说明

参数 说明
app_id 必须,创建 OAuth 应用后详情中的 App ID
response_type 必须,授权的类型,在 implicit 模式 中值必须为 "token"
redirect_uri 必须,授权成功后的回调地址,必须与控制台 OAuth 应用配置的 URL 一致,需要经过 urlencoded 编码
scope 允许的授权的范围,暂时没有实现此字段的相关功能,可不传

# 2. 重定向并返回 access_token

{redirect_uri}#access_token=9a617eb1dddc9fc7a480b0778173fd7f9db33938&state=123456lkjljkf3

当授权成功后,将会重定向到如上的链接,在 hash 中携带 access_token

# 3. 使用 access_token 请求 userInfo

authorization_code 模式 的第三步一样。

GET https://users.authing.cn/oauth/user/userinfo?access_token=...

或作为 Authoriztion 头:

Authorization: Bearer { access_token }

# password 模式

此模式要求有用户名和密码,且必须使用 POST 请求

password 模式

# 1. 发起授权

向以下这个地址发起 POST 请求:

https://sso.authing.cn/token

参数说明

参数 说明
app_id 必须,创建 OAuth 应用后详情中的 App ID
app_secret 必须,创建 OAuth 应用后详情中的 App Secret
grant_type 必须,授权的类型,在 password 模式 中值必须为 "password"
username 必须,用户邮箱
password 必须,用户密码

返回

{
  "access_token":"4331396b953d3de3bcf74c564455323d0989a9a0",
  "token_type":"Bearer",
  "expires_in":3599, // token 有效时间
  "refresh_token":"017888c6722e3433f3840a6708d9b79c23b310b8" // 可用此 token 来重新获取新的 token 而无需重新授权
}

# 2. 使用 access_token 请求 userInfo

authorization_code 模式 的第三步一样。

GET https://users.authing.cn/oauth/user/userinfo?access_token=...

或作为 Authoriztion 头:

Authorization: Bearer { access_token }

# client-credentials 模式

此模式用于获取对应 client 的所有用户信息,请谨慎使用,不支持刷新 token

# 1. 发起授权

向以下这个地址发起 POST 请求:

https://sso.authing.cn/token

参数说明

参数 说明
app_id 必须,创建 OAuth 应用后详情中的 App ID
app_secret 必须,创建 OAuth 应用后详情中的 App Secret
grant_type 必须,授权的类型,在 client_credentials 模式 中值必须为 "client_credentials"

返回

{
  "access_token":"4331396b953d3de3bcf74c564455323d0989a9a0",
  "token_type":"Bearer",
  "expires_in":3599, // token 有效时间
}

# 2. 使用 access_token 请求 userInfo

authorization_code 模式 的第三步一样。

GET https://users.authing.cn/oauth/user/userinfo?access_token=...

或作为 Authoriztion 头:

Authorization: Bearer { access_token }

# 常见问题

# 验证 access_token 的 URL 地址

GET
https://sso.authing.cn/authenticate?access_token=

验证 access_token

Path Paramter
access_token
OPTIONAL
string

access_token 的值

200: OK
{
  "state": 1,
  "isRevoked": false,
  "isDeleted": false,
  "_id": "5d60efdee3faa629cccc0dee",
  "id": "5d60efdee3faa629cccc0dee",
  "accessToken": "db8abb9e16de36f52da082a6dc9f20c378301fc8",
  "accessTokenExpiresAt": "2019-08-24T09:05:50.201Z",
  "scope": "user",
  "grantType": "implicit",
  "appId": "5d60e64f62554964c85b555e",
  "userOrClientId": "5cbecd1daee8f920472cb40a",
  "when": "2019-08-24T08:05:50.201Z",
  "iss": "https://sso.authing.cn",
  "sub": "5d60efdee3faa629cccc0dee",
  "aud": "5d60e64f62554964c85b555e",
  "exp": 1566637550201,
  "iat": 1566633950201,
  "user_id": "5d60efdee3faa629cccc0dee",
  "issued_to": "https://sso.authing.cn",
  "audience": "5d60e64f62554964c85b555e",
  "expires_in": 3360,
  "access_type": "offline"
}

# Token 有效时间

所有模式的 access_token 有效时间都是 1 小时,能够使用 refresh_token 的模式中的 refresh_token 的有效时间为 2 周。

# 四种模式的区别

关于这四种模式的应用场景和区别,建议浏览 理解 OAuth2.0,一般情况下只需开启 authorization_code 模式。