华为账号登录接入

2026-08-08hweihaobo-herbert👁 87 阅读7 分钟阅读📝 1009 字💬 0 评论
华为账号登录接入

华为账号登录接入总结(Web OAuth 2.0)

适用项目:Spring Boot 3 后端 + Nuxt3 前端博客系统
日期:2026-08-08

一、前置申请(华为开发者平台)

  1. 注册华为开发者联盟账号并完成个人实名认证(免费)
  2. 「管理中心 → 开发与服务 → Account Kit(账号服务)」开通
  3. 创建 Web 应用,获取凭据:
    • Client ID(OAuth 客户端 ID)
    • Client Secret(可重置,重置后旧值立即失效)
    • 回调地址https://你的域名/api/auth/oauth/huawei/callback
  4. 注意:SDK 配置里的 client_id / client_secret(AGC 凭据)与 OAuth 凭据是两套,登录只用 OAuth 那套,不要混淆

二、核心接口(关键:用 v3,不是 v2!)

环节 接口
授权 GET https://oauth-login.cloud.huawei.com/oauth2/v3/authorize
换 token POST https://oauth-login.cloud.huawei.com/oauth2/v3/token
用户信息 解码 token 响应中的 id_token(JWT)(v1/v2/v3 的 userinfo 接口均 404,不可用)

三、完整流程

1. 授权跳转

GET /oauth2/v3/authorize  ?response_type=code  &client_id={CLIENT_ID}  &redirect_uri={URL编码的回调地址}  &scope=openid%20profile  &state={随机state}

2. 回调参数(关键坑:华为的授权码参数名是 authorization_code,不是标准 OAuth 的 code

回调地址?authorization_code=EQEEAL8%2B...&state=...

3. 换 token

http
POST /oauth2/v3/tokenContent-Type: application/x-www-form-urlencodedgrant_type=authorization_codeclient_id={CLIENT_ID}client_secret={CLIENT_SECRET}code={authorization_code 的值,必须 URL 编码(含 + / = 特殊字符)}redirect_uri={URL编码的回调地址}

响应示例:

json
{  "scope": "profile openid",  "access_token": "DgEA...",  "token_type": "Bearer",  "expires_in": 3600,  "id_token": "eyJraWQi..."   ← 用户信息在这里}

4. 用户信息:解码 id_token(JWT)

JWT payload 字段:

字段 说明
openID 用户唯一标识(必含)
unionID 联盟 ID
displayName 昵称(可能为空)
headPictureURL 头像
email 邮箱
java
// JWT 解码(base64url)String[] parts = idToken.split("\\.");String payload = new String(Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8);// 解析 JSON 取 openID / displayName / headPictureURL / email

四、踩过的 5 个坑(按出现顺序)

# 现象 解决
1 回调参数名不是 code 而是 authorization_code MissingServletRequestParameterException: 'code' 回调同时接收 code + authorization_code 两个可选参数
2 code 含 +///= 特殊字符,拼 form body 前未编码 华为返回 invalid code URLEncoder.encode(code) 后再拼 body
3 接口版本用错(v2 的 userinfo 全 404) userinfo 返回 HTML 页面 整套改用 v3 接口
4 用户信息不在 userinfo 接口,而在 id_token(JWT)里 userinfo 404 / 解析失败 从 token 响应的 id_token 解码
5 中文昵称直接拼进 sendRedirect URL Unicode character [华] cannot be encoded 回调 URL 参数全部 URLEncoder.encode

五、后端实现要点(Spring Boot + hutool)

java
@Overridepublic String getAccessToken(String code) {    // code 含 + / = 等特殊字符,拼入 form body 前必须 URL 编码    String encodedCode = URLEncoder.encode(code, StandardCharsets.UTF_8);    String body = "grant_type=authorization_code&client_id=" + clientId            + "&client_secret=" + clientSecret            + "&code=" + encodedCode            + "&redirect_uri=" + encodedRedirectUri();    JSONObject json = JSON.parseObject(            HttpRequest.post(TOKEN_URL)                    .header("Content-Type", "application/x-www-form-urlencoded")                    .body(body).execute().body());    String idToken = json.getString("id_token");  // 缓存,用于解码用户信息    return json.getString("access_token");}

回调控制器(兼容标准 code 与华为 authorization_code):

java
@GetMapping("/{provider}/callback")public void callback(@PathVariable String provider,                     @RequestParam(required = false) String code,                     @RequestParam(required = false) String authorization_code,                     HttpServletResponse response) throws IOException {    // 华为回跳参数名为 authorization_code,GitHub/Gitee 为 code    String authCode = code != null ? code : authorization_code;    ...}

六、前端按钮

登录页加跳转链接:

html
<a :href="`${apiBase}/auth/oauth/huawei`">使用华为账号登录</a>

七、经验结论

  • 华为文档是 Angular SPA,爬虫抓不到正文,接口细节只能靠实测 + 社区博客(CSDN 提到 v3 是关键线索)
  • 华为 Account Kit Web 登录 = 标准 OAuth 2.0 授权码模式 + 用户信息从 id_token 解码
  • 与 GitHub/Gitee 的唯一本质差异:授权码参数名 authorization_code、接口版本 v3、用户信息走 id_token
  • 调试利器:在 provider 里加 System.out.println 打印 token 响应的完整字段(脱敏),一次就能定位问题
hweihaobo-herbert
技术博客作者
1009 字 · 0 评论
2026-08-08

评论 (0)

暂无评论,来写第一条吧

登录后发表评论