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

Laravel集成Azure B2C登录遇invalid_grant错误求助

Azure B2C获取Access Token时出现400 invalid_grant错误排查

问题描述

我正在尝试用Laravel(后端为API)和Angular(前端客户端)实现Azure B2C登录功能,目前已完成部分流程。计划在后端处理全部登录逻辑:用户点击“用Microsoft登录”后跳转至后端页面,完成认证操作后重定向到前端页面,并将access token存入Cookie。

已在后端web.php中定义了两个路由:一个用于跳转至Azure登录页,另一个作为回调路由。相关代码如下:

public function redirect()
{
    $length = mt_rand(43, 128);
    $bytes = random_bytes($length);
    $codeVerifier = rtrim(strtr(base64_encode($bytes), '+/', '-_'), '=');

    $state = Str::random(40);

    $query = http_build_query([
        'p' => 'B2C_1A_SIGNIN',
        'client_id' => config('services.azureadb2c.client_id'),
        'redirect_uri' => config('services.azureadb2c.redirect'),
        'response_type' => 'code',
        'scope' => 'openid',
        'state' => $state,
        'prompt' => 'login',
        'code_challenge' => $this->generateCodeChallenge($codeVerifier),
        'code_challenge_method' => 'S256',
    ]);

    session(['state' => $state, 'code_verifier' => $codeVerifier]);

    return redirect('https://' . config('services.azureadb2c.domain') . '.b2clogin.com/' . config('services.azureadb2c.domain') . '.onmicrosoft.com/b2c_1a_signin/oauth2/v2.0/authorize?' . $query);
}

public function callback(Request $request)
{
    $client = new Client();
    $response = $client->post("https://" . config('services.azureadb2c.domain') . ".b2clogin.com/" . config('services.azureadb2c.domain') . ".onmicrosoft.com/b2c_1a_signin/oauth2/v2.0/token?p=B2C_1A_SIGNIN", [
        'form_params' => [
            'grant_type' => 'authorization_code',
            'client_id' => config('services.azureadb2c.client_id'),
            'client_secret' => config('services.azureadb2c.client_secret'),
            'code' => $request->get('code'),
            'redirect_uri' => config('services.azureadb2c.redirect'),
            'code_verifier' => session('code_verifier'),
            'scope' => 'openid',
        ],
    ]);
    var_dump(json_decode($response->body()));
    exit;
}

private function generateCodeChallenge($codeVerifier) {
    $hash = hash('sha256', $codeVerifier, true);
    $codeChallenge = rtrim(strtr(base64_encode($hash), '+/', '-_'), '=');
    return $codeChallenge;
}

目前跳转流程正常,用户可正常跳转并输入凭证,但在回调环节获取到授权码后,发起POST请求获取access token时收到400错误,错误信息如下:

400 Bad Request response: {"error":"invalid_grant","error_description":"AADB2C90085: The service has encountered an internal error. Please reauthe (truncated...)

可能的原因排查

  • Redirect URI 不一致:检查redirect_uri在授权请求(redirect方法)、token请求(callback方法)以及Azure B2C应用注册中配置的地址是否完全一致,包括HTTP/HTTPS、端口、路径,任何细微差异都会导致invalid_grant。
  • Code Verifier 不匹配:确认code_verifier在session中存储的值与授权请求中生成的完全一致,注意session是否跨请求丢失,或者生成code challenge时的base64编码处理是否正确(比如是否正确替换了+/为-_并去掉末尾的=)。
  • 授权码已过期或重复使用:Azure B2C的授权码只能使用一次,且有效期很短(通常5分钟),如果回调中重复使用同一个授权码,或者请求延迟超过有效期,会触发该错误。
  • B2C策略名称不匹配:检查授权请求和token请求中的策略参数p=B2C_1A_SIGNIN是否与Azure B2C中配置的用户流名称完全一致,注意大小写和拼写。
  • Client Secret 错误:确认client_secret是否与Azure B2C应用注册中生成的密钥完全一致,注意密钥是否过期,或者复制时是否包含多余的空格。
  • Scope 参数不匹配:授权请求和token请求中的scope必须完全一致,当前代码中都是openid,但如果Azure B2C应用配置了额外的scope,需要确保两边同步。
  • Session 状态丢失:如果Laravel的session配置有问题,导致code_verifier或state无法正确读取,会影响token请求的验证逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:46:05