文档管理中心
指南元服务开发指导经营履约能力开发账号Account Kit通知事件

Account Kit通知事件

概述

华为账号提供了多种通知事件机制,方便元服务感知系统未成年人模式变化和用户信息变更。事件类型包含:

展开
事件类型 事件分类 描述
系统未成年人模式开启/关闭事件 客户端事件 元服务在前台时通过订阅系统公共事件,实时感知系统未成年人模式的开启/关闭状态。
用户信息变更事件 服务端事件 华为账号服务器向元服务服务端发送通知,告知用户及其账户信息的重要变更,如用户取消授权、注销账号、手机号变更等。

系统未成年人模式开启/关闭事件

场景介绍

元服务在前台时可以订阅Account Kit提供的系统未成年人模式公共事件,来感知系统未成年人模式的开启/关闭状态,以提供适龄内容。

事件说明

以下是系统未成年人模式开启/关闭发送的广播事件。

展开
事件名称 描述
COMMON_EVENT_MINORSMODE_ON usual.event.MINORSMODE_ON 表示系统未成年人模式开启事件。
COMMON_EVENT_MINORSMODE_OFF usual.event.MINORSMODE_OFF 表示系统未成年人模式关闭事件。
说明

主动开启系统未成年人模式,当前设备会发送系统未成年人模式开启事件。

开发前提

请先参考“开发准备”的配置签名和指纹章节,通过自动签名方式完成签名信息的配置。请注意,该接口无需配置公钥指纹、Client ID,也无需申请账号权限。

开发步骤

  1. 导入commonEventManager模块及相关公共模块。

    收起
    自动换行
    深色代码主题
    复制
    1. import { hilog } from '@kit.PerformanceAnalysisKit';
    2. import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';
  2. 创建订阅者,订阅系统未成年人模式开启或关闭事件。推荐在元服务Ability的onCreate生命周期中调用。

    收起
    自动换行
    深色代码主题
    复制
    1. // 订阅者信息
    2. const subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {
    3. events: [commonEventManager.Support.COMMON_EVENT_MINORSMODE_ON,
    4. commonEventManager.Support.COMMON_EVENT_MINORSMODE_OFF]
    5. };
    6. // 定义订阅者,如开发者使用await改写createSubscriber方法,需要把此变量定义到全局(struct外层)
    7. let subscriber: commonEventManager.CommonEventSubscriber | null = null;
    8. // 创建订阅者
    9. commonEventManager.createSubscriber(subscribeInfo)
    10. .then((commonEventSubscriber: commonEventManager.CommonEventSubscriber) => {
    11. // 这里获取到commonEventSubscriber对象需要暂存,用于后续事件回调。不可直接使用,否则会出现事件回调不生效的情况
    12. subscriber = commonEventSubscriber;
    13. // 订阅公共事件
    14. commonEventManager.subscribe(subscriber,
    15. (error: BusinessError, data: commonEventManager.CommonEventData) => {
    16. if (error) {
    17. dealCommonEventAllError(error);
    18. return;
    19. }
    20. if (data.event === commonEventManager.Support.COMMON_EVENT_MINORSMODE_ON) {
    21. // 订阅到开启事件,可以调用获取年龄段的接口,根据年龄段刷新内容展示,同时如开发者有缓存年龄段或系统未成年人模式开启状态,则需要刷新缓存
    22. return;
    23. }
    24. if (data.event === commonEventManager.Support.COMMON_EVENT_MINORSMODE_OFF) {
    25. // 订阅到关闭事件,关闭当前元服务的未成年人模式,刷新元服务内容展示,取消年龄限制,如开发者有缓存系统未成年人模式开启状态,则需要刷新缓存
    26. }
    27. });
    28. })
    29. .catch((error: BusinessError) => {
    30. dealCommonEventAllError(error);
    31. });
    收起
    自动换行
    深色代码主题
    复制
    1. function dealCommonEventAllError(error: BusinessError): void {
    2. hilog.error(0x0000, 'testTag', `Failed to subscribe. Code: ${error.code}, message: ${error.message}`);
    3. }

用户信息变更事件

场景介绍

通过订阅用户信息变更,您可以接收有关用户及其账户的重要更新。当用户及其账户信息发生变更时,华为账号服务器会发送通知到元服务,元服务可以根据通知消息进行自身业务处理。

事件说明

展开
消息名称 事件类型 事件描述
tokens-revoked https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked 用户取消元服务的授权
account-purged https://schemas.openid.net/secevent/risc/event-type/account-purged 用户注销华为账号
phone-modified https://schemas.openid.net/secevent/oauth/event-type/phone-modified 用户授权手机号变更

订阅用户信息变更

订阅步骤如下:

  1. 登录AppGallery Connect,选择“开发与服务”。

  2. 在项目列表选择项目。

  3. 进入“项目设置 > 开放能力管理”页面,点击“RISC”对应的“管理”。

  4. 点击“启用”按钮。

  5. 点击“订阅通知”按钮,在弹窗中配置“回调地址”及“订阅范围”,然后点击“提交”。

    说明

    回调地址:在开启订阅通知后,若华为用户信息发生变更,会发送通知消息到该地址。

    订阅范围:订阅的用户信息变更事件,详见事件说明

处理通知消息

华为账号服务器向元服务投递消息。元服务接收到消息后需要先对消息头中的令牌进行验签,确保消息的完整有效性后解析并获取用户信息变更事件详情。具体步骤如下:

  1. 验证消息头中的令牌签名。

    您可通过任何JWT库(例如:jwt.io)对其进行解析与验证。

    无论使用哪种库,您均需完成如下操作:

    1. 调用接口https://risc.cloud.huawei.com/v1beta/public/risc/.well-known/risc-configuration,获取发行者标识(issuer)与签名密钥证书URI(jwks_uri)。
    2. 通过依赖的JWT库,对消息头中的令牌进行解析,获取签名的KeyId。
    3. 通过签名的KeyId,从签名密钥证书URI中获取到JWT签名的公钥。
    4. 校验JWT签名中的aud与订阅用户信息变更中提供的Client ID一致。
    5. 校验JWT签名中的issuer与发行者标识(issuer)一致。

    具体验签逻辑,请参考如下示例代码:

    Maven依赖配置

    收起
    自动换行
    深色代码主题
    复制
    1. <dependencies>
    2. <dependency>
    3. <groupId>com.github.ben-manes.caffeine</groupId>
    4. <artifactId>caffeine</artifactId>
    5. <version>2.9.3</version> <!--此处替换为您项目需要的版本-->
    6. </dependency>
    7. <dependency>
    8. <groupId>com.auth0</groupId>
    9. <artifactId>jwks-rsa</artifactId>
    10. <version>0.21.2</version> <!--此处替换为您项目需要的版本-->
    11. </dependency>
    12. <dependency>
    13. <groupId>io.jsonwebtoken</groupId>
    14. <artifactId>jjwt-impl</artifactId>
    15. <version>0.11.5</version> <!--此处替换为您项目需要的版本-->
    16. </dependency>
    17. <dependency>
    18. <groupId>io.jsonwebtoken</groupId>
    19. <artifactId>jjwt-jackson</artifactId>
    20. <version>0.11.5</version> <!--此处替换为您项目需要的版本-->
    21. </dependency>
    22. <dependency>
    23. <groupId>com.alibaba.fastjson2</groupId>
    24. <artifactId>fastjson2</artifactId>
    25. <version>2.0.51</version> <!--此处替换为您项目需要的版本-->
    26. </dependency>
    27. <dependency>
    28. <groupId>org.apache.httpcomponents</groupId>
    29. <artifactId>httpclient</artifactId>
    30. <version>4.5.6</version> <!--此处替换为您项目需要的版本-->
    31. </dependency>
    32. <dependency>
    33. <groupId>org.projectlombok</groupId>
    34. <artifactId>lombok</artifactId>
    35. <version>1.18.26</version> <!--此处替换为您项目需要的版本-->
    36. </dependency>
    37. <dependency>
    38. <groupId>ch.qos.logback</groupId>
    39. <artifactId>logback-classic</artifactId>
    40. <version>1.2.11</version> <!--此处替换为您项目需要的版本-->
    41. </dependency>
    42. </dependencies>

    Java验签代码示例

    收起
    自动换行
    深色代码主题
    复制
    1. import com.alibaba.fastjson2.JSON;
    2. import com.alibaba.fastjson2.JSONObject;
    3. import com.auth0.jwk.JwkProvider;
    4. import com.auth0.jwk.UrlJwkProvider;
    5. import com.github.benmanes.caffeine.cache.CacheLoader;
    6. import com.github.benmanes.caffeine.cache.Caffeine;
    7. import com.github.benmanes.caffeine.cache.LoadingCache;
    8. import io.jsonwebtoken.Claims;
    9. import io.jsonwebtoken.IncorrectClaimException;
    10. import io.jsonwebtoken.JwsHeader;
    11. import io.jsonwebtoken.Jwt;
    12. import io.jsonwebtoken.JwtParser;
    13. import io.jsonwebtoken.Jwts;
    14. import io.jsonwebtoken.SigningKeyResolver;
    15. import io.jsonwebtoken.security.SignatureException;
    16. import lombok.Data;
    17. import lombok.extern.slf4j.Slf4j;
    18. import org.apache.http.HttpEntity;
    19. import org.apache.http.HttpStatus;
    20. import org.apache.http.client.config.RequestConfig;
    21. import org.apache.http.client.methods.CloseableHttpResponse;
    22. import org.apache.http.client.methods.HttpGet;
    23. import org.apache.http.config.Registry;
    24. import org.apache.http.config.RegistryBuilder;
    25. import org.apache.http.conn.socket.ConnectionSocketFactory;
    26. import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    27. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    28. import org.apache.http.impl.client.CloseableHttpClient;
    29. import org.apache.http.impl.client.HttpClients;
    30. import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    31. import org.apache.http.util.EntityUtils;
    32. import org.checkerframework.checker.nullness.qual.NonNull;
    33. import org.checkerframework.checker.nullness.qual.Nullable;
    34. import javax.net.ssl.SSLContext;
    35. import javax.net.ssl.TrustManagerFactory;
    36. import java.io.IOException;
    37. import java.net.URL;
    38. import java.security.Key;
    39. import java.security.KeyManagementException;
    40. import java.security.KeyStore;
    41. import java.security.KeyStoreException;
    42. import java.security.NoSuchAlgorithmException;
    43. import java.security.PublicKey;
    44. import java.util.Objects;
    45. import java.util.concurrent.TimeUnit;
    46. /**
    47. * 订阅和处理用户信息变更
    48. */
    49. @Slf4j
    50. public class RiscDemo {
    51. /**
    52. * 公开配置信息地址
    53. */
    54. private static final String PUBLIC_CONFIGURATION_URL = "https://risc.cloud.huawei.com/v1beta/public/risc/.well-known/risc-configuration";
    55. /**
    56. * 公开信息缓存
    57. */
    58. private final LoadingCache<String, PublicConfiguration> publicConfigurationCache = Caffeine.newBuilder()
    59. .expireAfterWrite(1, TimeUnit.DAYS)
    60. .build(key -> {
    61. HttpGet request = new HttpGet(PUBLIC_CONFIGURATION_URL);
    62. try (CloseableHttpResponse response = getClient().execute(request)) {
    63. HttpEntity responseEntity = response.getEntity();
    64. String ret = responseEntity != null ? EntityUtils.toString(responseEntity) : null;
    65. EntityUtils.consume(responseEntity);
    66. int statusCode = response.getStatusLine().getStatusCode();
    67. // http状态码不是200,抛出异常
    68. if (statusCode != HttpStatus.SC_OK) {
    69. throw new IOException("call failed! http status code: " + statusCode + ", response data: " + ret);
    70. }
    71. JSONObject configJson = (JSONObject) JSON.parse(ret);
    72. if (configJson == null) {
    73. throw new IllegalArgumentException("response param error! http status code: " + statusCode + ", response data: " + ret);
    74. }
    75. String issuer = configJson.getString("issuer");
    76. String jwksUri = configJson.getString("jwks_uri");
    77. if (Objects.isNull(issuer) || Objects.isNull(jwksUri)) {
    78. throw new IllegalArgumentException("response param error! http status code: " + statusCode + ", response data: " + ret);
    79. }
    80. PublicConfiguration publicConfiguration = new PublicConfiguration();
    81. publicConfiguration.setIssuer(issuer);
    82. publicConfiguration.setJwksUri(jwksUri);
    83. return publicConfiguration;
    84. }
    85. });
    86. /**
    87. * 公钥信息缓存
    88. */
    89. private final LoadingCache<String, PublicKey> publicKeyCache = Caffeine.newBuilder()
    90. .expireAfterWrite(1, TimeUnit.DAYS)
    91. .build(new CacheLoader<String, PublicKey>() {
    92. @Override
    93. public @Nullable PublicKey load(@NonNull String key) throws Exception {
    94. PublicConfiguration publicConfiguration = getPublicConfiguration();
    95. JwkProvider huaweiCerts = new UrlJwkProvider(new URL(publicConfiguration.getJwksUri()), null, null);
    96. return huaweiCerts.get(key).getPublicKey();
    97. }
    98. });
    99. /**
    100. * 调试方法入口
    101. * @param args main方法入参
    102. */
    103. public static void main(String[] args) {
    104. // 消息请求头中Authorization: Bearer <token>中的<token>
    105. String token = "<token>";
    106. // Client ID
    107. String clientId = "<Client ID>";
    108. Jwt<?, ?> jwt = new RiscDemo().validateSecurityEventToken(token, clientId);
    109. if (Objects.isNull(jwt)) {
    110. // 验签失败
    111. log.error("verify sign failed");
    112. } else {
    113. // 验签成功
    114. log.info("verify sign success");
    115. }
    116. }
    117. /**
    118. * 对Authorization头域中的token进行验签
    119. *
    120. * @param token 消息请求头中Authorization: Bearer <token>中的<token>
    121. * @param clientId clientId
    122. * @return 返回为null,则表示验签失败,否则表示验证成功
    123. */
    124. public Jwt<?, ?> validateSecurityEventToken(String token, String clientId) {
    125. try {
    126. // 公开配置信息中的issuer值
    127. String issuer = getPublicConfiguration().getIssuer();
    128. SigningKeyResolver signingKeyResolver = new SigningKeyResolver() {
    129. private PublicKey getPublicKey(JwsHeader<?> jwsHeader) {
    130. try {
    131. return publicKeyCache.get(jwsHeader.getKeyId());
    132. } catch (Exception e) {
    133. throw new RuntimeException(e);
    134. }
    135. }
    136. @Override
    137. public Key resolveSigningKey(JwsHeader jwsHeader, Claims claims) {
    138. return getPublicKey(jwsHeader);
    139. }
    140. @Override
    141. public Key resolveSigningKey(JwsHeader jwsHeader, String s) {
    142. return getPublicKey(jwsHeader);
    143. }
    144. };
    145. // 验证并解析消息内容
    146. JwtParser parser = Jwts.parserBuilder()
    147. .requireIssuer(issuer)
    148. .requireAudience(clientId)
    149. .setAllowedClockSkewSeconds(60)
    150. .setSigningKeyResolver(signingKeyResolver)
    151. .build();
    152. return parser.parse(token);
    153. } catch (IncorrectClaimException e) {
    154. // 消息的claim无效,针对异常进行处理(如:日志记录)
    155. log.error("claim invalid", e);
    156. } catch (SignatureException e) {
    157. // 验签失败,针对异常进行处理(如:日志记录)
    158. log.error("verify signature failed", e);
    159. } catch (Exception e) {
    160. // 其他异常,业务自行处理
    161. log.error("valid event token failed", e);
    162. }
    163. return null;
    164. }
    165. private PublicConfiguration getPublicConfiguration() {
    166. PublicConfiguration publicConfiguration = this.publicConfigurationCache.get("DEFAULT");
    167. if (publicConfiguration == null) {
    168. throw new IllegalArgumentException("public configuration get failed!");
    169. }
    170. return publicConfiguration;
    171. }
    172. private static CloseableHttpClient getClient() {
    173. PoolingHttpClientConnectionManager connectionManager = buildConnectionManager(
    174. new String[] {"TLSv1.2"}, new String[] {
    175. "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    176. "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
    177. });
    178. connectionManager.setMaxTotal(400);
    179. connectionManager.setDefaultMaxPerRoute(400);
    180. RequestConfig config = RequestConfig.custom()
    181. .setConnectionRequestTimeout(100)
    182. .setRedirectsEnabled(false)
    183. .build();
    184. return HttpClients.custom()
    185. .useSystemProperties()
    186. .setConnectionManager(connectionManager)
    187. .setDefaultRequestConfig(config)
    188. .build();
    189. }
    190. private static PoolingHttpClientConnectionManager buildConnectionManager(String[] supportedProtocols,
    191. String[] supportedCipherSuites) {
    192. PoolingHttpClientConnectionManager connectionManager = null;
    193. try {
    194. SSLContext sc = SSLContext.getInstance("TLSv1.2");
    195. TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    196. tmf.init((KeyStore) null);
    197. sc.init(null, tmf.getTrustManagers(), null);
    198. SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sc, supportedProtocols,
    199. supportedCipherSuites, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
    200. Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
    201. .register("http", new PlainConnectionSocketFactory())
    202. .register("https", sslsf)
    203. .build();
    204. connectionManager = new PoolingHttpClientConnectionManager(registry);
    205. } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException e) {
    206. log.error("build connect manager failed", e);
    207. }
    208. return connectionManager;
    209. }
    210. @Data
    211. static class PublicConfiguration {
    212. private String issuer;
    213. private String jwksUri;
    214. }
    215. }
  2. 处理消息体。

    • JSON对象格式消息体

      消息示例:用户注销华为账号

      收起
      自动换行
      深色代码主题
      复制
      1. {
      2. "iss": "id.cloud.huawei.com",
      3. "aud": "<Client ID>",
      4. "iat": 1727619834,
      5. "jti": "6672ed7d5c5e4c3c92f343ecac40f326",
      6. "events": {
      7. "https://schemas.openid.net/secevent/risc/event-type/account-purged": {
      8. "subject": {
      9. "extra": "<触发事件用户的OpenID>",
      10. "iss": "id.cloud.huawei.com",
      11. "sub": "<触发事件用户的UnionID>",
      12. "subject_type": "iss_sub"
      13. }
      14. }
      15. }
      16. }

      消息示例:用户取消元服务的授权

      收起
      自动换行
      深色代码主题
      复制
      1. {
      2. "iss": "id.cloud.huawei.com",
      3. "aud": "<Client ID>",
      4. "iat": 1750403661,
      5. "jti": "97af1abdbbcd4f00a6d8b74c9b1bbb56",
      6. "events": {
      7. "https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked": {
      8. "subject": {
      9. "extra": "<触发事件用户的OpenID>",
      10. "iss": "id.cloud.huawei.com",
      11. "sub": "<触发事件用户的UnionID>",
      12. "subject_type": "iss_sub"
      13. },
      14. "scopes": [
      15. "phone",
      16. "userConsent",
      17. "openid",
      18. "email"
      19. ]
      20. }
      21. }
      22. }

      消息示例:用户授权手机号变更

      收起
      自动换行
      深色代码主题
      复制
      1. {
      2. "iss": "id.cloud.huawei.com",
      3. "aud": "<Client ID>",
      4. "iat": 1750385669,
      5. "jti": "c27c197ba5c94081aa32b8dbc52389f3",
      6. "events": {
      7. "https://schemas.openid.net/secevent/oauth/event-type/phone-modified": {
      8. "subject": {
      9. "extra": "<触发事件用户的OpenID>",
      10. "iss": "id.cloud.huawei.com",
      11. "sub": "<触发事件用户的UnionID>",
      12. "subject_type": "iss_sub"
      13. }
      14. }
      15. }
      16. }
    • JSON数组格式消息体

      消息示例:用户注销华为账号

      收起
      自动换行
      深色代码主题
      复制
      1. [
      2. {
      3. "iss": "id.cloud.huawei.com",
      4. "aud": "<Client ID>",
      5. "iat": 1750385669,
      6. "jti": "6672ed7d5c5e4c3c92f343ecac40f326",
      7. "events": {
      8. "https://schemas.openid.net/secevent/risc/event-type/account-purged": {
      9. "subject": {
      10. "extra": "<触发事件用户的OpenID>",
      11. "iss": "id.cloud.huawei.com",
      12. "sub": "<触发事件用户的UnionID>",
      13. "subject_type": "iss_sub"
      14. }
      15. }
      16. }
      17. },
      18. {
      19. "iss": "id.cloud.huawei.com",
      20. "aud": "<Client ID>",
      21. "iat": 1750385669,
      22. "jti": "6672ed7d5c5e4c3c92f343ecac40f325",
      23. "events": {
      24. "https://schemas.openid.net/secevent/risc/event-type/account-purged": {
      25. "subject": {
      26. "extra": "<触发事件用户的OpenID>",
      27. "iss": "id.cloud.huawei.com",
      28. "sub": "<触发事件用户的UnionID>",
      29. "subject_type": "iss_sub"
      30. }
      31. }
      32. }
      33. }
      34. ]

      消息示例:用户取消元服务的授权

      收起
      自动换行
      深色代码主题
      复制
      1. [
      2. {
      3. "iss": "id.cloud.huawei.com",
      4. "aud": "<Client ID>",
      5. "iat": 1750403661,
      6. "jti": "97af1abdbbcd4f00a6d8b74c9b1bbb56",
      7. "events": {
      8. "https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked": {
      9. "subject": {
      10. "extra": "<触发事件用户的OpenID>",
      11. "iss": "id.cloud.huawei.com",
      12. "sub": "<触发事件用户的UnionID>",
      13. "subject_type": "iss_sub"
      14. },
      15. "scopes": [
      16. "phone",
      17. "userConsent",
      18. "openid",
      19. "email"
      20. ]
      21. }
      22. }
      23. },
      24. {
      25. "iss": "id.cloud.huawei.com",
      26. "aud": "<Client ID>",
      27. "iat": 1750403661,
      28. "jti": "97af1abdbbcd4f00a6d8b74c9b1bbb57",
      29. "events": {
      30. "https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked": {
      31. "subject": {
      32. "extra": "<触发事件用户的OpenID>",
      33. "iss": "id.cloud.huawei.com",
      34. "sub": "<触发事件用户的UnionID>",
      35. "subject_type": "iss_sub"
      36. },
      37. "scopes": [
      38. "phone",
      39. "userConsent",
      40. "openid",
      41. "email"
      42. ]
      43. }
      44. }
      45. }
      46. ]

      消息示例:用户授权手机号变更

      收起
      自动换行
      深色代码主题
      复制
      1. [
      2. {
      3. "iss": "id.cloud.huawei.com",
      4. "aud": "<Client ID>",
      5. "iat": 1750385669,
      6. "jti": "c27c197ba5c94081aa32b8dbc52389f3",
      7. "events": {
      8. "https://schemas.openid.net/secevent/oauth/event-type/phone-modified": {
      9. "subject": {
      10. "extra": "<触发事件用户的OpenID>",
      11. "iss": "id.cloud.huawei.com",
      12. "sub": "<触发事件用户的UnionID>",
      13. "subject_type": "iss_sub"
      14. }
      15. }
      16. }
      17. },
      18. {
      19. "iss": "id.cloud.huawei.com",
      20. "aud": "<Client ID>",
      21. "iat": 1750385669,
      22. "jti": "c27c197ba5c94081aa32b8dbc52389f4",
      23. "events": {
      24. "https://schemas.openid.net/secevent/oauth/event-type/phone-modified": {
      25. "subject": {
      26. "extra": "<触发事件用户的OpenID>",
      27. "iss": "id.cloud.huawei.com",
      28. "sub": "<触发事件用户的UnionID>",
      29. "subject_type": "iss_sub"
      30. }
      31. }
      32. }
      33. }
      34. ]

    其中,各字段含义如下:

    展开
    参数 描述
    aud Client ID(与订阅用户信息变更中提供的Client ID一致)。
    iss 消息投递者标识,固定值“id.cloud.huawei.com”。
    iat 生成该事件的UTC时间戳(秒级)。
    jti 唯一随机字符串,用于标识此消息体,开发者可根据此字段来识别重投消息体。
    events 用户信息变更事件与事件消息体,格式为json。key是用户信息变更事件类型,value为其对应事件消息信息。
    subject

    用户信息变更事件对应的消息体,格式为json,包含字段说明如下:

    - sub:触发事件用户的UnionID(用户在同一个开发者下的所有元服务,此值唯一)。具体格式要求请参考OpenID和UnionID的格式说明

    - subject_type:固定为“iss_sub”。

    - extra:触发事件用户的OpenID(用户在同一个元服务中,此值唯一)。具体格式要求请参考OpenID和UnionID的格式说明

    - iss:标识消息投递者,固定为“id.cloud.huawei.com”。

    scopes 取消授权的scope列表,格式为json数组。在事件类型为【https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked】时才存在此字段。
在 指南 中进行搜索
请输入您想要搜索的关键词