全部产品
云市场

移动端和桌面端应用的OAuth2.0接入流程

更新时间:2019-09-06 11:12:26

本文档主要描述移动端和桌面客户端如何通过OAuth2.0接口接入CCP。

1. 介绍

由于是端应用,您的应用中无法存放机密信息,比如 App 的 secret。

对于移动端(Android, IOS),一般是要唤醒授权App授权,需要使用 URL Schema。

对于桌面客户端(mac,linux windows 桌面端),可以通过回环IP地址(Loopback IP address)唤醒授权端, 也可以通过 URL Schema。

还有一种方式也比较常用,就是通过webview 请求 web 服务应用的方式。

(1) 原理:

授权码模式:同Web服务应用接入的授权码模式基本相同,除了获取token的步骤不需要提供Secret参数(因为没有web服务端,而secret不能放在客户端)。但是可以通过挑战码的方式加强安全性。

(2) 用例图

b1

(3) Proof Key 机制的原理

Native 应用支持 Proof Key 机制,用于每次获取授权码以及用授权码换取访问令牌。

说明 这一机制可以减轻针对授权码截获的攻击。

1. Native 应用应用生成:code_verifier,并保存好这个随机字符串。

说明 codeverifier是一个高熵值的随机字符串,其取值为:[A-Z] / [a-z] / [0-9] / “-“ / “.” / ““ / “~”,长度限制为:43 ~ 128 个字符。

2. 应用根据transform的方式选择生成code_challenge。应用在申请授权码的同时提交:code_challenge 以及生成code_challenge的方式。

  1. code_challenge = transform(code_verifier, [Plain|S256])
方式 取值
plain 如果 transform的方式选择为:plain,那么code_challenge与code_verifier的值相同。
S256 如果transform的方式选择为:S256,那么code_challenge等于code verifier的 SHA256 哈希值。

code_challenge=BASE64URL-Encode(SHA256(ASCII(code_verifier)))

说明 哈希算法的输入为:code_verifier 的 ASCII 编码串,哈希算法的输出字符串需要进行 BASE64-URL 编码。code_challenge选择方式计算示例:

如果应用采用方式为 S256,生成code_verifier的值为:dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk,那么code_challenge为:E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM

3. 应用获取授权码后,在使用授权码换取访问令牌时,服务端通过计算判断是否颁发令牌。

授权码需包括code_verifier,服务端按照应用选择的transform方式对code_verifier进行计算,将结果与code_challenge进行对比,如果一致则颁发访问令牌。

2. 接入前提

(1) 创建Domain

首先,您需要在CCP官网控制台 https://ccp.console.aliyun.com 创建一个域(Domain)。创建完成后,会提供一个3级API域名 https://{domainId}.api.alicloudccp.com

(2) 去第三方开发者页面申请AppId和AppSecret

比如淘宝开发者页面。 参考: https://open.taobao.com/doc.htm?docId=102635&docType=1

将申请的AppId和AppSecret 配置到 Domain 中。

(3) 创建App(Client)

创建App,选择类型为”Native应用”。确定App的访问Scope: 支持Scope列表, 这个Scope要在用户授权页面展示。创建完成,可以得到 AppId(ClientId) 和 Secret(ClientSecret)。这个是授权认证的凭证,Secret要注意保密不要泄露。

(4) 规划 redirect_uri

自定义URL Schema(Android, iOS)

APP需要注册自己的URL Scheme,用来唯一标识一个App。Scheme格式:<scheme域名>://<path>?<params>=<value>

自定义Lookback IP Address(桌面客户端)

可以启动一个本地web 服务,监听端口,如 : http://127.0.0.1:3000/callback 或者 http://[::1]:3000

3. 获取 OAuth2.0 Access Token 步骤

(1) /authorize 接口

API 请求语法:

  1. GET /v2/oauth/authorize?client_id=<appId>&redirect_uri=<redirect_uri>&scope=<scope>&state=[state]&prompt=[prompt] HTTP/1.1
  2. Host: {domainId}.auth.alicloudapp.com
参数 是否必选 描述
client_id AppId, 如果没有请到官网控制台去创建。
redirect_uri 回调地址: 告诉认证服务在授权认证流程完成后重定向到哪里。一般是您的客户端应用提供的一个URL Schema或者LookBack IP Address。比如:meeting://authorize/, 认证服务在授权完成后,会redirect到这个地址并且带上一次性的code: meeting://authorize/?code=xxxx,然后您需要使用这个code完成后续流程。
注意:这个redirect_uri 必须和您创建App时填写的redirect_uri 一致。
scope 访问范围列表,描述您的Web服务应用需要的访问权限范围,将在用户同意授权页面展示。请看支持Scope列表
response_type 此处固定为”code”
state 否,但推荐使用 如果请求中包含这个参数,认证服务器在重定向的时候会原封不动返回, 用于防止重放攻击。如:meeting://authorize/?code=xxxx&state=abc
code_challenge_method 否,但推荐使用 如果不指定此参数,则默认取值为:plain。
code_challenge 否,但推荐使用 根据客户端指定的 code_challenge_method,对随机生成的 code_verifier 进行转换和编码,转换的结果作为 code_challenge 参数的值在授权码请求中使用。
说明: 如果不指定此参数,则无法使用 Proof Key 机制,在使用授权码换取令牌时也不需要指定相应的 code_verifier,若授权码被截获可以直接被用于换取访问令牌。

发送此请求后,CCP Auth服务会引导用户去登录。用户登录完成后,如果用户是第一次登录并且请求参数设置了prompt=consent,则会重定向到 consent 页面,否则会直接重定向到请求参数中的redirect_uri,比如: meeting://authorize/?code=xxxx&state=abc

在此步骤中,用户可以决定是否授权给Web服务应用。如果不同意授权,则流程终止。 如果同意授权,将重定向到第一步请求中的redirect_uri, 比如: meeting://authorize/?code=xxxx&state=abc

(3) 通过 code 获取 AccessToken

应用获取到 code 后,调用下面的接口换取 AccessToken。

API 请求语法:

  1. POST /v2/oauth/token HTTP/1.1
  2. Host: {domainId}.auth.alicloudapp.com
  3. Content-Type: application/x-www-form-urlencoded
  4. code=xxx\
  5. &client_id=your_app_id\
  6. &redirect_uri=http://a.com/callback\
  7. &grant_type=authorization_code\
  8. &code_verifier=xxxx
参数 是否必选 描述
code 一次性code,使用过一次后即失效。
client_id AppId
redirect_uri 这个redirect_uri 必须和您创建App时填写的redirect_uri 一致。
grant_type 根据OAuth2.0规范,此处的值固定为”authorization_code”。
code_verifier 初始请求中生成的 code verifier,对应于授权码请求中的 code_challenge 参数。

返回

名称 位置 类型 必选 说明
access_token body string 生成的 id_token,有效期2小时。
refresh_token body string 用来刷新 access_token, 有效期比较长,一般为7天。
expires_time body string access_token 的有效期。
token_type body string 固定为 Bearer

样例:

  1. HTTP/1.1 200 OK
  2. Content-Type: application/json
  3. {
  4. "access_token":"Aiasd76YSo23...LSdyssd2",
  5. "expires_time":"2019-11-11T10:10:10.009Z",
  6. "token_type":"Bearer",
  7. "refresh_token":"LSLKdklksd...li3ew6"
  8. }
  • 请忽略返回的数据中的非必选字段。

4. 调用CCP 服务API

客户端可以直接使用 AccessToken 调用 CCP API。只需在请求头的Authorization中带上AccessToken。

调用方式举例:

  1. POST /v2/files/list HTTP/1.1
  2. Host: {domainId}.api.alicloudapp.com
  3. Authorization: Bearer {AccessToken}
  4. Content-Type: application/json
  5. {
  6. "drive_id": "1"
  7. }

5. 刷新Token

(1) 请求方式举例:

  1. POST /v2/oauth/token/v2/auth/refresh_token HTTP/1.1
  2. Host: {domainId}.api.alicloudapp.com
  3. Content-Type: application/x-www-form-urlencoded
  4. refresh_token=xxx\
  5. &client_id=xxx\
  6. &client_secret=xxx\
  7. &grant_type=refresh_token

请求参数

参数名称 是否必选 描述
refresh_token 用授权码换取访问令牌时获得的刷新令牌。
client_id 应用的身份 ID。
grant_type 根据 OAuth 2.0 协议, 取值为:refresh_token。
client_secret 应用的密钥,用作换取访问令牌时鉴定应用身份的密码。

(2) 返回

  1. HTTP/1.1 200 OK
  2. Content-Type: application/json
  3. {
  4. "access_token":"xxxxxxxxx",
  5. "expires_in":3920,
  6. "expires_time":"2019-11-11T10:10:10.009Z",
  7. "token_type":"Bearer"
  8. }

返回参数

参数名称 描述
access_token 新的访问令牌。应用可以使用新的访问令牌来访问阿里云 API。
expires_in 访问令牌的剩余有效时间,单位为秒。
expires_time 访问令牌的失效时间,ISO时间格式。
token_type 访问令牌的类型。取值为:Bearer。

说明: 本次请求的返回值与用授权码换取访问令牌的返回值一致,但不包含 refresh_token。