HarmonyOS 鸿蒙NEXT Push Kit v3 REST API 服务端推送持续返回 80200001

HarmonyOS 鸿蒙NEXT Push Kit v3 REST API 服务端推送持续返回 80200001 谢谢各位老师,问题已解决:是因为我没有把官方说明文档里的“调用推送服务REST API”和“示例代码”这两部分同步给AI,所以AI不知道怎么改,导致一直在没出问题的地方打转。

归根结底还是我的问题:认为这两部分不重要,更根本的原因是对于整个流程不熟悉,后面也会加强相关方面的学习。

以下是一些不相关的碎碎念:

确实之前一直用AI做的都是一些比较小且独立的功能,第一次涉及系统方面的权限/api调用,我一开始甚至连生成鉴权令牌都看不懂,只觉得怎么这里也给一个json那里也给一个json(现在我的文件夹里还有好多json,一个也不敢删……)所以最开始完全依赖AI,出问题之后才开始找官方说明文档一点点排查错误(然后把最关键的信息漏掉了)。

烧了小一百块钱tokens修改迭代了23个版本之后总算成功实现了这个功能,手机通知横幅弹出、通知铃声响起的时候收获了无与伦比的开心。谢谢各位老师的解答和帮助!祝老师们永远不会遇到bug!

=======================================

各位老师好,我是一个完全的新人,正在试图通过AI给我个人开发的应用加入PushKit推送功能,但是调试了一整天还是没能成功,所以让AI总结了一下遇到的问题,想麻烦各位老师帮忙看一下是哪里出错了、应该如何修改。如果有描述不到位的地方,请各位老师批评指正。

环境:

  • HarmonyOS NEXT,targetSdkVersion 6.0.2(22)
  • 服务端:Node.js(Vercel Serverless),TypeScript
  • Push Kit v3 接口

已完成的配置:

  • AGC 已开启 Push Kit 服务
  • 客户端 pushService.getToken() 成功获取 token(长度112),token 在 AGC 控制台"测试消息"功能可正常推送成功
  • 从 AGC 控制台下载了服务账号密钥 JSON 文件,包含 project_id、sub_account、key_id、private_key

服务端鉴权代码(Node.js,使用 Web Crypto API):

// JWT 生成 + 换取 access_token
async function getHuaweiAccessToken(): Promise<string> {
    // 从环境变量读取密钥文件中的字段
    // HUAWEI_KEY_ID = "3cc5d5be66e5470fb2a47f8cc34fe5ae"
    // HUAWEI_SUB_ACCOUNT = "117526863"
    // HUAWEI_PROJECT_ID = "101653523863958499"
    // HUAWEI_PRIVATE_KEY = PEM 格式 RSA 私钥
    const pem = rawKey.replace(/\\n/g, '\n')
    const b64 = pem.replace(/-----BEGIN PRIVATE KEY-----|-----END PRIVATE KEY-----|\s/g, '')
    const keyBytes = Uint8Array.from(atob(b64), c => c.charCodeAt(0))
    const cryptoKey = await crypto.subtle.importKey(
        'pkcs8', keyBytes.buffer,
        { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, ['sign']
    )
    const now = Math.floor(Date.now() / 1000)
    // JWT header: { alg: 'RS256', kid: keyId, typ: 'JWT' }
    // JWT payload: { iss: subAccount, aud: 'https://oauth-login.cloud.huawei.com/oauth2/v3/token', iat: now, exp: now+3600 }
    // ... base64url 编码 + RS256 签名 ...
    // 换取 access_token
    const res = await fetch('https://oauth-login.cloud.huawei.com/oauth2/v3/token', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=' + jwt
    })
    // res.ok = true,成功拿到 access_token(前12位形如 DgEBAMCoANoS)
}

推送调用代码:

await fetch('https://push-api.cloud.huawei.com/v3/101653523863958499/messages:send', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json;charset=utf-8',
        'Authorization': `Bearer ${accessToken}`,
        'push-type': '0'
    },
    body: JSON.stringify({
        validate_only: false,
        message: {
            token: ["设备token(112位)"],
            android: {
                notification: { title: "标题", body: "内容", click_action: { type: 3 } }
            }
        }
    })
})

响应:

{"code":"80200001","msg":"Authentication Error","requestId":"..."}

已排查项:

  1. ✅ JWT exchange 成功(能拿到 access_token)
  2. ✅ URL 中 projectId = 密钥文件中 project_id = 101653523863958499
  3. ✅ 使用 v3 接口
  4. ✅ 设备 token 有效(AGC 控制台测试成功)
  5. ✅ iss = sub_account(改成 project_id 会报 “jwt iss not matched”)
  6. ❓ 服务账号是否需要在某个地方单独授权 Push 发送权限?

问题: access_token 拿到了,但 push API 始终返回 80200001,请问是哪里配置有问题?服务账号是否需要在 AGC 控制台某处手动授权?


更多关于HarmonyOS 鸿蒙NEXT Push Kit v3 REST API 服务端推送持续返回 80200001的实战教程也可以访问 https://www.itying.com/category-93-b0.html

9 回复

你的 JWT 换取 access_token 成功,说明 OAuth 流程没问题,但这个 access_token 没有 Push Kit 的调用权限。

个人觉得问题根源

你的服务账号密钥(agc-apiclient-*.json)只是"项目级"凭证

但 Push Kit v3 需要额外在 API Console 中"启用 Push Kit API"并关联服务账号

去agc 平台申请一下, 如下图

cke_2014.png

最后我强烈建议你仔细看下 这个教程 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/push-kit-introduction
ai 可以帮你写代码 但是你却丢失了对于整体项目的把握, 你可以让ai 给你写 某一块的代码 ,而不是全部, 要不有些错误 真的不好定位的 , 如有帮助给个采纳谢谢

更多关于HarmonyOS 鸿蒙NEXT Push Kit v3 REST API 服务端推送持续返回 80200001的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


谢谢老师,问题已经解决啦!确实不能太过依赖AI,至少不能全部依赖AI,以后我也会更加注意的,感谢老师的教导和帮助!

80200001是典型的身份验证失败,根源还是对Push Kit流程不熟悉导致关键信息遗漏。

开发系统级API时,官方文档是AI无法替代的基础,尤其鉴权、REST调用这类流程强依赖的场景,必须先通读流程再结合AI调试,能大幅减少无效迭代成本。

后续开发建议先按文档走通一遍流程,再用AI优化实现,效率会高很多。

很不错

你现在这套流程里最大的点是:你拿到的 access_token(OAuth2 换出来的)并不能用于 HarmonyOS NEXT / Push Kit v3 的下发鉴权。Push v3 在 HarmonyOS 5/Next 及以上要求的是:直接用“服务账号生成的 JWT Token”放到推送接口的 Authorization 里,而不是先去 oauth-login.../token 换 access_token。否则就很容易出现你这个 80200001 Authentication Error。文档对 80200001 的原因里也明确提到:HarmonyOS 5+ 不再支持 OAuth2.0 开放鉴权,应使用 JWT 鉴权。

同时你 JWT 里用的是 RS256,而 Push 的服务账号 JWT 指南要求 PS256(RSA-PSS)


你该怎么改(按优先级)

1) 不要再 exchange access_token,直接把“JWT Token”用于推送

把推送请求头从:

  • Authorization: Bearer ${accessToken}

改成:

  • Authorization: Bearer ${jwtToken}

并且这个 jwtToken 就是你用服务账号私钥签出来的那串 xxx.yyy.zzz

官方示例也是“Authorization 里直接放 JWT Token”。

2) JWT 算法用 PS256,不要用 RS256

  • Header:alg 必须是 PS256,并带 kid
  • 签名:RSA-PSS + SHA-256(saltLength 通常 32)
  • Payload:iss=sub_accountaud 固定为 https://oauth-login.cloud.huawei.com/oauth2/v3/tokeniat/exp 秒级时间戳,exp=iat+3600

3) 确认“服务账号密钥”就是为 Push API 创建的(不需要额外在 AGC 再授权)

一般不需要你额外点“授权发送权限”,但要确保:

  • 这个服务账号密钥是在 API Console 里为“推送服务 API”创建的服务账号密钥(选对项目)。
  • push 请求 URL 的 projectId密钥文件 project_id、以及 AGC 中该应用所属项目ID一致。

Node.js 最短可用写法(jsonwebtoken)

import jwt from 'jsonwebtoken'

function buildPushJwt(privateJson: any) {
  const header = { alg: 'PS256', kid: privateJson.key_id, typ: 'JWT' }
  const now = Math.floor(Date.now() / 1000)
  const payload = {
    iss: privateJson.sub_account,
    aud: 'https://oauth-login.cloud.huawei.com/oauth2/v3/token',
    iat: now,
    exp: now + 3600,
  }
  return jwt.sign(payload, privateJson.private_key.replace(/\\n/g, '\n'), {
    algorithm: 'PS256',
    header,
  })
}

// 推送时直接用 jwtToken
const jwtToken = buildPushJwt(privateJson)

await fetch(`https://push-api.cloud.huawei.com/v3/${privateJson.project_id}/messages:send`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json;charset=utf-8',
    'Authorization': `Bearer ${jwtToken}`,
    'push-type': '0',
  },
  body: JSON.stringify({
    validate_only: false,
    message: {
      token: ['...112位token...'],
      // 这里消息体结构你后续再按 HarmonyOS Next 的字段规范调整
    },
  }),
})

你现在的“JWT exchange 成功拿到 access_token”并不能证明推送鉴权链路是对的;Push v3 要的是上面这种“JWT 直签直用”。


如果改完仍报 80200001,最可能的只剩两类

  1. projectId 不属于这个 service account key 所在项目(最常见)
  2. JWT 生成不符合规范(alg 不是 PS256、时间戳不对、kid/iss 不对)

你可以把你生成出来的 JWT 的 header/payload(解码后,不要贴签名和私钥)、以及推送 URL 里的 projectId 发我,我能帮你一眼对齐哪里不匹配。

Sources:

80200001 认证错误

错误信息

Authentication Error.

错误描述

认证错误。

可能原因

  1. 发送消息时未添加Authorization参数或Authorization的值为空。
  2. 用于申请JWT Token的Project Id和推送消息的Project Id不一致。
  3. Authorization参数中的JWT Token与实际应用不匹配。

处理步骤

请根据响应消息中的提示,排查请求头中Authorization参数鉴权失败是否存在以下情况:

  1. 请检查发送消息时是否添加Authorization参数或Authorization的值为空。
  2. 请参考鉴权令牌生成步骤中的步骤二,检查推送请求URL(https://push-api.cloud.huawei.com/v3/[projectId]/messages:send)中的projectId,确保与您当前应用所属的项目保持一致。
  3. 请检查Authorization参数中的JWT Token与实际应用是否匹配,详情参见基于服务账号生成鉴权令牌

重新生成JWT Token后再发送请求。

请求头中Authorization参数鉴权失败,请检查:

  1. 发送消息时未添加Authorization参数或Authorization的值为空。
  2. 用于申请JWT Token的Project Id和推送消息的Project Id不一致。
  3. Authorization参数中的JWT Token与实际应用不匹配,详情参见基于服务账号生成鉴权令牌

请重新生成JWT Token后再推送消息。

说明:当前新创建的HarmonyOS Next应用使用V3版本的Rest API下发消息时。鉴权方式只支持JWT Token令牌;不支持Access Token的鉴权方式。

80200001 表示请求参数错误。常见原因:Authorization Token 过期或无效;请求体 JSON 格式不正确(如缺少必要字段或类型错误);推送目标(token/topic)无效。请检查 Token 是否在有效期内、请求体是否符合 Push Kit v3 API 规范,以及 target 参数格式。

问题出在获取 access_token 时 JWT 的 payload 缺少推送服务所需的 scope 声明。
80200001 是 OAuth 权限不足导致的认证错误,即使拿到了 token,若无 scope,推送 API 也会拒绝访问。

正确构造 JWT 的方式是在 payload 中加入:

{
  "iss": "sub_account值",
  "aud": "https://oauth-login.cloud.huawei.com/oauth2/v3/token",
  "iat": 当前秒级时间戳,
  "exp": iat + 3600,
  "scope": "https://push-api.cloud.huawei.com"
}

其余头部 kid 使用 Key ID,签名算法 RS256 不变。用此 JWT 换取的 access_token 即可通过调用推送接口的 Authorization: Bearer ... 验证。

另外确保请求头中携带 push-type: 0,URL 的 projectId 使用项目 ID。把官方“调用推送服务 REST API”示例与完整 JWT 生成代码同步给 AI 即可修复。

回到顶部