You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keycloak客户端发起账户关联报错invalid_token解决方案

Keycloak 15.0.2 + Laravel Socialite 客户端账户关联invalid_token报错解决方案

问题场景

在使用Keycloak 15.0.2、Laravel框架配合Socialite做用户认证,实现客户端发起的账户关联功能时触发报错。

问题表现

  • 发起客户端账户关联请求失败,控制台输出CLIENT_INITIATED_ACCOUNT_LINKING_ERROR类型的WARN日志,错误标识为invalid_token
  • 关联URL按照官方规则由PHP后端生成,生成hash时已采用UTF8编码,所有官方要求的前置条件均已满足
  • 本地环境测试所有应用未启用HTTPS,登录功能正常,JWT Token中已包含所需的角色映射:
"account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  • 访问生成的关联URL时返回“Invalid request”,Keycloak控制台提示token无效。

原有实现代码

hash生成代码

$keycloack_user = Socialite::driver('keycloak')->user();
$bearerToken = $keycloack_user->token;
$tokenParts = explode(".", $bearerToken);
$tokenHeader = base64_decode($tokenParts[0]);
$tokenPayload = base64_decode($tokenParts[1]);
$jwtHeader = json_decode($tokenHeader);
$jwtPayload = json_decode($tokenPayload);

$client_id = $jwtPayload->azp;
$host = $jwtPayload->iss;

$session_state = $jwtPayload->session_state;

$nonce = Str::random(20);
$provider = "google";

$input = $nonce . $session_state . $client_id . $provider;
$utf8encoded = utf8_encode($input);
$hashed = hash('sha256', $utf8encoded);
$encoded = rtrim(strtr(base64_encode($hashed), '+/', '-_'), '=');

关联URL构造代码

$redirect_uri = urlencode(...);
$full_url = $host . "/broker/". $provider ."/link?client_id=". $client_id ."&redirect_uri=". $redirect_uri ."&nonce=". $nonce ."&hash=" . $encoded;

根因与解决方案

Keycloak要求校验的hash是对原始二进制哈希结果做Base64URL编码,原有代码中hash函数默认返回十六进制字符串,导致最终生成的hash不符合校验规则。
修改hash生成逻辑,调用hash方法时传入第三个参数为true,返回原始二进制数据即可:

$hashed = hash('sha256', $utf8encoded, true);

内容的提问来源于stack exchange,提问作者Steven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:06:03