文档管理中心
我的

基于OAuth 2.0开放鉴权

概述

OAuth 2.0是一个开放授权协议,它允许开发者应用在不获取用户名与密码的前提下,访问用户授权的资源(OAuth 2.0相关协议规范,请访问OAuth 2.0官方网站)。

您可以在华为开发者联盟API Console上创建OAuth 2.0客户端ID,通过该客户端ID接入华为帐号,生成Access Token,调用华为公开API,访问用户授权的资源。

授权模式介绍

OAuth 2.0协议定义了四种授权模式:授权码模式(Authorization Code)、客户端模式(Client Credentials)、授权码扩展模式(PKCE)、设备码模式(Device Code)。

当前华为帐号已支持该四种授权模式,您可根据自身需要,选择其中一种或者多种完成华为帐号接入,获取Access Token。

各模式主要区别如下:

展开

授权模式

描述

使用场景

授权码模式(Authorization Code)

用户授权,生成授权码Code,开发者应用通过Code获取Tokens(如:Access Token、Refresh Token、ID Token)。

应用有服务器,可存储应用密钥,与华为帐号服务器进行密钥交互。

客户端模式(Client Credentials)

无需用户授权,开发者应用生成一个鉴权令牌,调用华为公开应用级接口。

调用应用级接口。

授权码扩展模式(PKCE)

用户授权,生成授权码Code,开发者应用通过Code获取Tokens(如:Access Token、Refresh Token、ID Token)。

应用无服务器,无法存储应用密钥,通过随机字符串与华为帐号服务器进行交互。

设备码模式(Device Code)

弱输入设备,用户通过手机扫码授权,开发者应用获取Tokens(如:Access Token、Refresh Token、ID Token)。

不支持浏览器或输入受限的设备(如儿童手表等),在手机等设备上扫描二维码并确认授权,与华为帐号服务器交互。

说明
  • 开发者应用在选择客户端授权模式获取鉴权令牌时,每次调用授权接口均需在请求体中传入“client_id”与“client_secret”(客户端秘钥),如开发者有更高安全要求,推荐使用基于Service Account开放鉴权方式接入。
  • 开发者应用在Access Token有效期(expires_in)内,请勿过于频繁请求,否则可能会被流控(当前应用级Access Token流控阈值为1000次/5分钟,详情参见Access Token流控机制)。您可根据有效期,提前重新申请或通过Refresh Token刷新鉴权令牌,同时您也可根据鉴权令牌超时错误返回(NSP_STATUS=6,请参见错误与异常机制),重新触发申请鉴权令牌流程。
  • 各个鉴权模式获得到的Access Token,如果是通过curl命令或者Postman等工具手工获取,需注意JSON字符串中的转义符,请把“\/”还原为“/”,替换后才是正确的Access Token。如果是从代码运行获取,则采用任意基于Service Account开放鉴权的第三方库均能正确解析JSON串,获取到正确的Access Token。

接入前准备

若您首次集成华为帐号,请先完成API Console接入,生成OAuth 2.0客户端ID,具体步骤及支持此类鉴权的公开API类型表,请参见API Console操作指南。

说明
  • 若您已注册过,生成了客户端ID(如移动、智慧屏等客户端ID),且希望同时实现多种场景接入,则无需重新注册,请忽略此章节。

    例如:某公司已经注册生成了APPID-1,完成App集成接入,但是Web也想接入华为帐号,则可忽略此章节,继续使用已有的APPID-1,实现接入。

  • 若您的应用属于AppGallery Connect类型应用(如何查看该类型应用的详细信息,请参见查看应用信息),则请注意,该类型应用的Client ID值对应本文中的客户端ID(参数:client_id),Client Secret值对应本文中的客户端密钥(参数:client_secret)。

授权码模式(Authorization Code)

同时支持App与Web应用的接入,呈现授权页面给用户,开发者应用在获取用户的授权码Code后,可以凭借此授权码换取Access Token,调用华为公开API,访问用户授权的数据资源。

具体接入流程如下:

1-2:用户选择华为帐号登录,开发者应用发起授权码Code请求。

3-4:华为帐号服务器呈现授权页面给用户,用户确认授权。

5-6:华为帐号服务器通过开发者应用配置的回调地址,返回授权码Code。

7:开发者应用发起Code换Token请求。

8:华为帐号服务器返回令牌(Access Token)、用户信息(ID Token)。

具体操作步骤如下:

  1. 授权码Code请求。

    开发者应用发起授权码模式流程,拼接一个授权码Code请求,访问华为帐号OAuth服务。

    链接请求格式如下:

    https://oauth-login.cloud.huawei.com/oauth2/v3/authorize?
    response_type=code&
    access_type=offline&
    state=state_parameter_passthrough_value&
    nonce=nonce_parameter_passthrough_value&
    client_id=<客户端ID>&
    redirect_uri=<应用的回调地址>&
    scope=openid+<业务的权限scope>&
    display=touch
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    response_type

    M

    填写为“code”,表示为授权码模式。

    client_id

    M

    在接入前准备中得到的OAuth 2.0客户端ID,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client ID。

    redirect_uri

    M

    授权后要回调的地址URL,即开发者应用接收授权码code的URL。如回调地址为:https://www.thirdwebdemo.com/redirect_url,

    说明

    在回调地址后可添加单个其他参数为:https://www.thirdwebdemo.com/redirect_url?somearg=XXXXXX。

    回调地址相关,具体请参见设置回调地址。

    scope

    M

    一个字符串数组,以空格分开(URL编码后空格变为加号+),必须包含字符串“openid”,其他权限请参见业务的scope描述,根据需要拼接权限项scope。

    access_type

    O

    枚举值,确定响应是否包含Refresh Token,Refresh Token用于刷新Access Token。

    • 为offline时,返回响应包含Refresh Token。
    • 为online或不传该值时,返回响应不包含Refresh Token。

    state

    O

    推荐使用高品质随机数生成器构造的字符串,或者使用保存在后端的密钥对部分会话状态变量进行签名从而生成的哈希串;满足正则匹配“^[0-9a-zA-Z:/\.]+$”,建议长度在100字符以内,授权服务器在回调时(重定向用户浏览器到“redirect_uri”时),会在uri中原样回传该参数。OAuth2.0标准协议建议,利用state参数来防止CSRF攻击。

    nonce

    O

    随机值,用于防重放攻击。在返回的JWT数据ID Token中原封不动保留。

    补充说明:

    1)不弹授权页面的场景,仅当code_challenge_method不为空(即PKCE模式授权)才会原封不动保留nonce值,否则nonce为default;

    display

    O

    授权页面呈现样式。

    • 如果应用为App,填写“touch”。
    • 如果应用为Web,填写“page”。

    默认为“page”。

  2. 用户登录及授权。

    当请求跳转到OAuth服务,OAuth服务会引导用户进行授权,弹出一个授权页面给用户,显示应用的名称和图标,以及该应用所申请授权的Scope权限列表,输入华为帐号及密码完成登录授权。

  3. 返回授权码Code。

    OAuth服务通过302跳转,将响应值授权码Code,通过回调地址redirect_uri,返回给应用。

    • 如果用户同意授权,则回调请求中带有授权码Code。示例如下:
      https://www.thirdwebdemo.com/redirect_url?
      code=<返回的授权码Code>&
      state=state_parameter_passthrough_value
    • 如果用户不同意授权,则回调请求中包含错误消息。示例如下:
      https://www.thirdwebdemo.com/redirect_url #error=1107&error_description=access+denied

  4. 授权码Code换取鉴权令牌。

    应用在获取到授权码Code后,再次请求OAuth服务,调用接口(https://oauth-login.cloud.huawei.com/oauth2/v3/token),通过授权码Code换取Access Token、Refresh Token以及ID Token。

    请求消息

    请通过POST方式调用,示例如下:

    POST /oauth2/v3/token HTTP/1.1
    Host: oauth-login.cloud.huawei.com
    Content-Type: application/x-www-form-urlencoded
     
    grant_type=authorization_code&
    code=<返回的授权码Code>&
    client_id=<客户端ID >&
    client_secret=<客户端密钥>&
    redirect_uri=<应用的回调地址>
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    grant_type

    M

    OAuth 2.0规范定义的字段,必须为“authorization_code”。

    code

    M

    与3中返回的授权码Code一致,Code有效期为5分钟,且只能请求一次。

    client_id

    M

    在接入前准备中得到的OAuth 2.0客户端ID,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client ID。

    client_secret

    M

    在接入前准备中给客户端ID分配的密钥,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client Secret。

    redirect_uri

    M

    与1中传入的回调地址一致。

    响应消息
    HTTP/1.1 200 OK
    Content-Type: text/html;charset=UTF-8
     
    {
        "access_token": "<返回的Access Token>",
        "expires_in": 3600,
        "refresh_token": "<返回的Refresh Token>",
        "scope": "profile openid",
        "token_type": "Bearer",
        "id_token": "<返回的JWT格式的ID Token>"
    }
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    access_token

    M

    用户的Access Token。

    expires_in

    M

    Access Token的剩余有效期,单位:秒。

    scope

    M

    生成的Access Token中包含的scope。

    token_type

    M

    固定返回Bearer,标识返回Access Token的类型。

    id_token

    M

    返回JWT格式数据,包含用户基本帐号、用户邮箱等信息。

    refresh_token

    O

    如1的入参中包含access_type=offline,则会返回此参数,该参数用于刷新Access Token。

    至此,开发者应用已经完成授权码模式(Authorization Code)的接入,获得到了用户的基本帐号信息 。ID Token具体解析请参见ID Token字段解析。

客户端模式(Client Credentials)

不需要用户进行授权,开发者应用可通过此模式生成一个鉴权令牌,访问华为公开应用级接口API。

具体接入流程步骤如下:

1:开发者服务器请求令牌Token。

2:华为帐号服务器返回应用级令牌Token。

请求鉴权令牌的具体操作步骤如下:

开发者应用发起客户端模式流程,直接调用华为帐号服务器的接口(https://oauth-login.cloud.huawei.com/oauth2/v3/token),获取一个应用级鉴权令牌。

请求消息

请通过POST方式调用,示例如下:

POST /oauth2/v3/token HTTP/1.1
Host: oauth-login.cloud.huawei.com
Content-Type: application/x-www-form-urlencoded
 
grant_type=client_credentials&
client_id=<客户端ID >&
client_secret=<客户端密钥>
展开

参数名称

必选(M)/可选(O)

参数说明

grant_type

M

填写为“client_credentials”,表示为客户端模式。

client_id

M

在接入前准备中得到的OAuth 2.0客户端ID,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client ID。

client_secret

M

在接入前准备中给客户端ID分配的密钥,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client Secret。

响应消息

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
 
{
  "access_token": "<返回的Access Token>",
  "expires_in": 3600,
  "token_type": "Bearer"
}
展开

参数名称

必选(M)/可选(O)

参数说明

access_token

M

应用级Access Token。

expires_in

M

Access Token的剩余有效期,单位:秒。

token_type

M

固定返回Bearer,标识返回Access Token的类型。

至此,开发者应用已经完成客户端模式(Client Credentials)的接入,开发者应用可凭借此鉴权令牌访问华为公开的应用级接口API。

授权码扩展模式(PKCE)

此模式为授权码的扩展模式,若开发者应用无服务端,无法存储用户密钥,则推荐此模式完成鉴权,通过应用客户端接入获取鉴权令牌,无需密钥交付,有效提升开发者应用的安全防护。

具体接入流程步骤如下:

1-3:用户选择华为帐号登录,开发者客户端准备并存储随机字符串与其编码值,发起包含编码值的授权码Code请求。

4-5:华为帐号服务器呈现页面给用户,用户确认授权。

6:华为帐号服务器通过开发者应用配置的回调地址,返回授权码Code。

7:开发者客户端发起Code换Token请求,包含应用存储的随机字符串。

8:华为帐号服务器返回令牌(Access Token)、用户信息(ID Token)。

具体操作步骤如下:

  1. 授权码Code请求。

    开发者应用发起授权码扩展模式流程,调用前需准备一个随机字符串(code_verifier,如:UUID.randomUUID().toString()),选择编码方法(code_challenge_method)对该随机字符串进行编码得到编码值(code_challenge),将code_verifier本地存储,拼接一个包含code_challenge_method和code_challenge的授权码Code请求,请求访问华为OAuth服务。

    链接请求格式如下:

    https://oauth-login.cloud.huawei.com/oauth2/v3/authorize?
    response_type=code&
    state=state_parameter_passthrough_value&
    nonce=nonce_parameter_passthrough_value&
    code_challenge=ovoy4lehgHbv8uNmif_hak3bH2_Ylk6_fWP0UL232QQ&
    code_challenge_method=S256&
    client_id=<客户端ID>&
    redirect_uri=<应用的回调地址>&
    scope=openid+<业务的权限scope>&
    display=touch
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    response_type

    M

    填写为“code”,表示为授权码扩展模式。

    client_id

    M

    在接入前准备中得到的OAuth 2.0客户端ID,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client ID。

    redirect_uri

    M

    授权后要回调的地址URL,即开发者应用接收授权码code的URL。如回调地址为:https://www.thirdwebdemo.com/redirect_url,

    说明

    在回调地址后可添加单个其他参数为:https://www.thirdwebdemo.com/redirect_url?somearg=XXXXXX。

    回调地址相关,具体请参见设置回调地址。

    code_challenge_method

    M

    对code_verifier进行编码的方法。当前支持两个枚举值,建议S256。

    • plain:原文,不编码
    • S256:code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))

    code_challenge

    M

    code_verifier进行编码后的值。

    scope

    M

    一个字符串数组,以空格分开(URL编码后空格变为加号+),必须包含字符串“openid”,其他权限请参见业务的scope描述,根据需要拼接权限项scope。

    state

    O

    推荐使用高品质随机数生成器构造的字符串,或者使用保存在后端的密钥对部分会话状态变量进行签名从而生成的哈希串;满足正则匹配“^[0-9a-zA-Z:/\.]+$”,建议长度在100字符以内,授权服务器在回调时(重定向用户浏览器到“redirect_uri”时),会在uri中原样回传该参数。OAuth2.0标准协议建议,利用state参数来防止CSRF攻击。

    nonce

    O

    随机值,用于防重放攻击。在返回的JWT数据id_token值中原封不动保留。

    补充说明:

    1)不弹授权页面的场景,仅当code_challenge_method不为空(即PKCE模式授权)才会原封不动保留nonce值,否则nonce为default;

    display

    O

    授权页面呈现样式。

    • 如果应用为App,填写“touch”。
    • 如果应用为Web,填写“page”。

    默认为“page”。

  2. 用户登录及授权。

    当请求跳转到OAuth服务,OAuth服务会引导用户进行授权,弹出一个授权页面给用户,显示应用的名称和图标,以及该应用所申请授权的Scope权限列表,输入华为帐号密码完成登录授权。

  3. 返回授权码。

    OAuth服务通过302跳转,将响应值授权码Code通过回调地址redirect_uri,返回给应用。

    如果用户同意授权,则回调请求中带有授权码Code。示例如下:

    https://www.thirdwebdemo.com/redirect_url?
    code=<返回的授权码Code>&
    state=state_parameter_passthrough_value

    如果用户不同意授权,则回调请求中包含错误消息。示例如下:

    https://www.thirdwebdemo.com/redirect_url #error=1107&error_description=access+denied

  4. 授权码Code换取鉴权令牌。

    应用在获取到授权码Code后,再次请求OAuth服务,调用接口(https://oauth-login.cloud.huawei.com/oauth2/v3/token),通过授权码Code换取Access Token、Refresh Token以及ID Token。

    请求消息

    请通过POST方式调用,示例如下:

    POST /oauth2/v3/token HTTP/1.1
    Host: oauth-login.cloud.huawei.com
    Content-Type: application/x-www-form-urlencoded
     
    grant_type=authorization_code&
    code=<返回的授权码Code>&
    client_id=<客户端ID >&
    code_verifier= 123444444dfd4sadfsdwew321454567587658776t896fdfgdscvvbfxdgfdgfdsfasdfsdgd233&
    redirect_uri=<应用的回调地址>
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    grant_type

    M

    OAuth 2.0规范定义的字段,必须为“authorization_code”。

    code

    M

    与3中返回的授权码Code一致,Code有效期为5分钟,且只能请求一次。

    client_id

    M

    在接入前准备中得到的OAuth 2.0客户端ID,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client ID。

    code_verifier

    M

    随机字符串,必须与1中编码前的字符串一致,用来验证authorize请求和token请求来自于同一个客户端。

    redirect_uri

    M

    与1中传入的回调地址一致。

    响应消息

    HTTP/1.1 200 OK
    Content-Type: text/html;charset=UTF-8
     
    {
        "access_token": "<返回的Access Token>",
        "expires_in": 3600,
        "scope": "profile openid",
        "token_type": "Bearer", 
        "id_token": "<返回的JWT格式的ID Token>"
    }
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    access_token

    M

    用户的Access Token。

    expires_in

    M

    Access Token的剩余有效期,单位:秒。

    scope

    M

    生成的Access Token中包含的Scope。

    token_type

    M

    固定返回Bearer,标识返回Access Token的类型。

    id_token

    M

    返回JWT格式数据,包含用户基本帐号、用户邮箱等信息。

    至此,开发者应用已经完成授权码扩展模式(PKCE)的接入,获得到了用户的基本帐号信息。ID Token具体解析请参见ID Token字段解析。

设备码模式(Device Code)

对于弱输入设备(不支持浏览器或输入受限的设备,如儿童手表),推荐使用此类模式接入华为帐号,通过华为帐号扫码获取到设备码,用户授权后,凭借此设备码换取鉴权令牌,访问用户授权的数据资源。

具体接入流程步骤如下:

1:开发者应用请求设备码、用户码。

2-3:华为帐号服务器返回用户码Code、设备码Code。

4:开发者应用生成二维码并呈现。

5-8:用户通过手机等终端扫描二维码,确认登录授权。

9:开发者服务器周期性用设备码Code请求换取Token。

10:华为帐号服务器在用户确认授权后,返回令牌(Access Token)、用户信息(ID Token)。

具体操作步骤如下:

  1. 设备码Code请求。

    开发者应用发起设备码模式流程,拼接一个设备码Code请求,调用华为OAuth服务获取该应用当前的设备码与用户码。

    请求消息

    请通过POST方式调用,示例如下:

    POST /oauth2/v3/device/code HTTP/1.1
    Host: oauth-login.cloud.huawei.com
    Cache-Control: no-cache
     
    client_id=<客户端ID >&
    scope=openid+<业务所需的权限scope>
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    client_id

    M

    在接入前准备中得到的OAuth 2.0客户端ID,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client ID。

    scope

    M

    一个字符串数组,以空格分开(URL编码后空格变为加号+),必须包含字符串“openid”,其他权限请参见业务的scope描述,根据需要拼接权限项scope。

    响应消息

    {
      "create_time": 1569813512,
      "device_code": "<返回的设备码device code>",
      "expire_in": 1800,
      "interval": 3,
      "scan_expire_in": 120,
      "user_code": "<返回的用户码user code>",
      "verification_url": "https://oauth-login1.cloud.huawei.com/oauth2/v3/device"
    }
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    create_time

    M

    Unix时间戳,用户码user code创建时间,二维码有效时间以这个时间为基准。

    device_code

    M

    设备码device code,可用于生成单次令牌Access Token。

    expire_in

    M

    device code的过期时间,单位为:秒,到期后device code不能换Access Token。

    interval

    M

    device code换Access Token轮询间隔时间,单位为:秒,轮询次数限制小于expire_in/interval。

    user_code

    M

    用户码,用于生成二维码。用户可通过华为帐号扫码功能,扫描二维码后弹出授权页面,进行确认授权。

    scan_expire_in

    M

    user code到期时间,如果在这个时间内不扫码,user code变为不可用,需要重新获取,单位为:秒。

    说明

    请您勿对此参数进行限制,可能因为业务需要对其进行调整。

    verification_url

    M

    user code校验URL,负责展示登录授权页面。

  2. 扫码用户登录及授权。

    开发者应用在获取到授权码Code请求的响应后,根据响应体中的校验URL(verification_url)与用户码user code,生成一个二维码。

    请求格式如下

    https://oauth-login1.cloud.huawei.com/oauth2/v3/device?
    user_code=<返回的用户码user code>&
    lang=zh-cn
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    user_code

    M

    1响应中返回的用户码user code。

    lang

    O

    语言码,如zh-cn、en-us、en-gb。

    • 浏览器模式时以浏览器给的accept-language为默认语言。
    • 华为帐号扫码时,以EMUI的环境语言为默认语言。
    • 显式传参,则以传参为准。

    开发者应用可以通过开源组件生成二维码(如:构建码生成功能),在弱输入设备屏幕上显示二维码,如下:

    用户通过手机扫码(如华为帐号扫码功能),对弱输入设备呈现的二维码进行扫码后,弹出一个授权页面,显示应用的名称和图标,以及该应用所申请授权的scope权限列表。

    说明

    如果华为帐号没有登录,会提示输入帐号密码或扫码,确认登录后,才会弹出授权页面。

    允许授权后返回授权成功页面。

  3. 返回鉴权令牌。

    弱输入设备中的开发者应用,在获得1的响应后,根据响应体中的interval为时间间隔,轮询调用接口(https://oauth-login.cloud.huawei.com/oauth2/v3/token),直到获取令牌Access Token,或轮询周期为止(最长为:1800秒)。

    请求消息

    请通过POST方式调用,示例如下:

    POST /oauth2/v3/token HTTP/1.1
    Host: oauth-login.cloud.huawei.com
    Content-Type: application/x-www-form-urlencoded
     
    grant_type= device_code &
    code=<返回的设备码Device Code>&
    client_id=<客户端ID >&
    client_secret=<客户端密钥>
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    grant_type

    M

    填写为“device_code”,设备码模式。

    code

    M

    1响应中返回的设备码device_code。

    client_id

    M

    在接入前准备中得到的OAuth 2.0客户端ID,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client ID。

    client_secret

    M

    在接入前准备中给客户端ID分配的密钥,对于AppGallery Connect类应用,该值为应用中OAuth 2.0客户端ID(凭据)的Client Secret。

    响应消息
    HTTP/1.1 200 OK
    Content-Type: application/json;charset=UTF-8
    Cache-Control: no-store
    Pragma: no-cache
     
    {
        "access_token": "<返回的Access Token>",
        "expires_in": 3600,
        "refresh_token": "<返回的Refresh Token>",
        "scope": "openid https://www.huawei.com/auth/drive.app.file",
        "token_type": "Bearer", 
        "id_token": "<返回的JWT格式的ID Token>",
        "open_id": "<返回的OPENID>"
    }
    展开

    参数名称

    必选(M)/可选(O)

    参数说明

    access_token

    M

    用户的Access Token。

    expires_in

    M

    Access Token的剩余有效期,单位:秒。

    scope

    M

    生成的Access Token中包含的scope。

    token_type

    M

    固定返回Bearer,标识返回Access Token的类型。

    id_token

    M

    返回JWT格式数据,包含用户基本帐号、用户邮箱等信息。

    refresh_token

    M

    本模式默认返回此参数,该参数用于刷新令牌Access Token。

    open_id

    M

    本模式默认返回open_id。

    至此,开发者应用已经完成设备码模式(Device Code)的接入,获得到了用户的基本帐号信息。ID Token具体解析请参见ID Token字段解析。

刷新令牌

用户级Access Token存在有效期,过期后不可用,如果继续调用访问用户授权的数据资源,会导致鉴权失败。

在授权码模式中,授权码Code请求中建议增加access_type=offline的入参,如此,则在生成Access Token的同时,也生成Refresh Token(注意,二者不可替用),而设备码模式默认同时返回Refresh Token。

其中,Refresh Token的有效期较长(有效期180天),在有效期内,应用可直接通过Refresh Token调用OAuth服务的接口(https://oauth-login.cloud.huawei.com/oauth2/v3/token),获取新的Access Token,避免重新弹出用户授权页面去引导用户再次进行登录授权。

请求示例

请通过POST方式调用,示例如下:

POST /oauth2/v3/token HTTP/1.1
Host: oauth-login.cloud.huawei.com
Content-Type: application/x-www-form-urlencoded
 
grant_type=refresh_token&
client_id=<客户端ID>&
client_secret=<客户端密钥 >&
refresh_token=<已经授权获得的Refresh Token,需UrlEncode编码>

响应示例

HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Cache-Control: no-store
 
{
  "access_token": "<新的Access Token>",
  "expires_in": 3600,
  "id_token": "<返回的JWT格式的ID Token >",
  "scope": "<授权的scope>",
  "token_type": "Bearer"
}

调用API

应用调用华为API时,把已获得API调用授权的令牌Access Token,放在Authorization头部来进行鉴权。

示例一:调用用户级接口。您在申请授权码Code请求时,scope入参中包含调用该接口的权限项,才能获取用户授权的资源(如:调用用户级接口/user/exampleInterface1,则可将获取的用户级Access Token放在请求头Header中来调用此接口)。

请通过POST方式调用,示例如下:

POST /user/exampleInterface1 HTTP/1.1
Host: <XXX>
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Cache-Control: no-cache
Authorization: Bearer <已经获得的用户级Access Token>

示例二:调用应用级接口。开发者应用需先在API Console的API库中启用相应Kit,才能调用该Kit的应用级接口(如:调用应用级接口/app/exampleInterface2,则可将获取的应用级Access Token放在请求头Header中来调用此接口)。

请通过POST方式调用,示例如下:

POST /app/exampleInterface2 HTTP/1.1
Host: <XXX>
Content-Type: application/x-www-form-urlencoded
Accept: application/json
Cache-Control: no-cache
Authorization: Bearer <已经获得的应用级Access Token>

令牌过期

如前文所述,令牌存在有效期,其中Access Token(1小时)、Refresh Token的有效期较长(180天)。但是除了令牌自然过期失效,还存在如下场景,将导致令牌被吊销而失效:

  • 用户修改了帐户密码,则该用户所有令牌均被吊销;
  • 用户冻结了帐号,则该用户所有令牌均被吊销;
  • 用户变更或删除安全帐号,则该用户所有令牌均被吊销;
  • 用户进行了帐号销户动作,则该用户所有令牌均被吊销;
  • 用户在帐号中心 -》帐号安全 -》登录设备管理中,移除了一台登录过的设备,则该用户在此设备生成的令牌均被吊销;
  • 用户在帐号的隐私中心 -》通知对您帐号的访问中,主动取消对某个应用的授权,则该用户对此应用生成的令牌均被吊销。

ID Token验证签名

说明

ID Token本地验证签名相关代码,请参考示例代码。

  1. 根据通用的JWT库(如jwt.io),对JWT格式的ID Token(24小时内生成的)进行解析。

    示例代码
    DecodedJWT decoder = JWT.decode(idToken);

  2. 从https://oauth-login.cloud.huawei.com/.well-known/openid-configuration的响应消息体中获取jwks_uri的属性值,该属性值为公钥URI,调用该URI,在响应消息体中获取keys的属性值。应用服务器根据keys的属性值生成公钥,对该公钥进行缓存(推荐缓存周期 24 小时)。

    示例代码
    private  Map<String,RSAPublicKey> keyId2PublicKey = new HashMap<String, RSAPublicKey>();
    ...
    JSONArray keys = getJwks();// 通过GET请求访问公钥URI,得到keys键值对
    for (int i = 0; i < keys.size();i++) {
        String kid = keys.getJSONObject(i).getString("kid");
        keyId2PublicKey.put(kid, getRsaPublicKeyByJwk(keys.getJSONObject(i)));
    }
    
    // 根据key键值对,生成公钥
    private static RSAPublicKey getRsaPublicKeyByJwk(JSONObject jwkObject) throws InvalidPublicKeyException {
    	Map<String, Object> additionalAttributes = new HashMap<String, Object>();
    	additionalAttributes.put("n", jwkObject.getString("n"));
    	additionalAttributes.put("e", jwkObject.getString("e"));
    	List<String> operations = new ArrayList<String>();
    	Jwk jwk = new Jwk(jwkObject.getString("kid"),jwkObject.getString("kty"),jwkObject.getString("alg"),
    			jwkObject.getString("use"),operations,null,null,null,
    			additionalAttributes);
    	 return ( RSAPublicKey )jwk.getPublicKey();
    }

  3. 应用服务器可以根据1解析的keyId从缓存中得到公钥。

    示例代码
    keyId2PublicKey.get(decoder.getKeyId());

  4. 验证签名。ID Token是JWT格式的,验证ID Token签名可使用JWT库,例如jwt.io。

    示例代码
    Algorithm algorithm = Algorithm.RSA256(keyId2PublicKey.get(decoder.getKeyId()) , null);
    JWTVerifier verifier = JWT.require(algorithm).build();
    //验证签名
    verifier.verify(decoder);

  5. 验证ID Token中iss字段的值是否等于“https://accounts.huawei.com”。

    示例代码
    private static final String ID_TOKEN_ISSUE = "https://accounts.huawei.com";
    decoder.getIssuer().equals(ID_TOKEN_ISSUE);

  6. 验证ID Token中aud字段的值等于应用的client_id(应用的client_id是AppGallery Connect应用中OAuth 2.0客户端ID(凭据)的Client ID)。

    示例代码
    private final static String CLIENT_ID = "XXX";
    decoder.getAudience().get(0).equals(CLIENT_ID);

  7. 验证ID Token中的过期时间(exp字段)是否已过期。

    示例代码
    verifier.verify(decoder);//过期,会抛出TokenExpiredException异常,详见说明

  8. 如果以上验证均通过,则表示用户ID Token验证通过,应用可直接解析ID Token中的用户信息。

    示例代码
    JSONObject jsonObject = JSONObject.parseObject(new String(Base64.decodeBase64(decoder.getPayload())));

说明

如果用户手机的当前时间比标准时间慢,则可能导致签名校验失败,抛出异常com.auth0.jwt.exception.InvalidClaimException并提示“The Token can't be used before ...”,请您酌情处理(如:重试、校准用户手机时间)。

ID Token字段解析

应用对ID Token字段进行签名验证,解析后得到字段映射表与生成ID Token的scope包含的权限项OpenID、email、profile。ID Token具体解析请参见ID Token字段解析。

Access Token流控机制

华为OAuth当前应用级Access Token的流控阈值为1000个/5分钟,5分钟内申请Access Token超过1000个,后续将提示被流控,无法申请。5分钟后重置,可以再次申请。如果您的应用申请应用级Access Token出现被流控的情况,请参见下面解决方案。

解决方案

在应用级Access Token 1小时有效期内重复使用,降低应用级Access Token的申请频率,单应用服务器1个小时内申请一次即可。

错误码

请参见错误与异常机制。