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

如何在Google Sign In中向PHP验证器传递JWT Token并完成验证?

问题:PHP集成Google Sign In后端验证失败

背景

网站原本仅支持8-9位用户编号+4位PIN码登录,现在要集成企业邮箱的Google Sign In提升安全性。目前前端Google登录按钮已可正常触发登录,能获取用户邮箱信息,但后端verifier.php无法完成JWT验证,不清楚正确的实现方式。

前端测试代码(已可获取用户信息)

<script src="https://accounts.google.com/gsi/client" async defer></script>
<div id="g_id_onload"
     data-client_id="xxxxxx.apps.googleusercontent.com"
     data-auto_select="false"
     data-itp_support="true"
     data-auto_prompt="false"
     data-ux_mode="redirect"
     data-login_uri="http://localhost/verifier.php"
     data-hd="xxx"
     data-locale="vi">
</div>
<div class="g_id_signin" data-type="standard" data-shape="pill"
     data-theme="outline"
     data-text="continue_with"
     data-size="large"
     data-locale="vi"
     data-logo_alignment="left">      
</div>
<p id="account"></p>
</body>
<script>
function handleCredentialResponse(response) {
  const responsePayload = decodeJwtResponse(response.credential);
  console.log('ID: '+responsePayload.sub);
  console.log('Name: ' + responsePayload.name);
  console.log('Email: ' + responsePayload.email);
  var username = responsePayload.email.split('@')[0];
  console.log(username);
  document.getElementById('account').innerHTML='welcome '+ responsePayload.name+' /// '+username;
}
function decodeJwtResponse(token) {
    var base64Url = token.split(".")[1];
    var base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
    var jsonPayload = decodeURIComponent(
      atob(base64)
        .split("")
        .map(function (c) {
          return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
        })
        .join("")
    );

    return JSON.parse(jsonPayload);
}
</script>

注:上述脚本仅用于测试,可正确获取用户邮箱及用户名

当前后端代码(无法运行)

<?php
require_once 'C:\xampp\htdocs\google-api-php-client--PHP8.0\vendor\autoload.php';
$CLIENT_ID= 'xxxxx.apps.googleusercontent.com'
$id_token: eyJhbGciOiJSUzI1NiIsImtpZCI6IjFhYWU4ZDdjOTIwNThiNWVlYTQ1Njg5NWJmODkwODQ1NzFlMzA2ZjMiLCJ0eXAiOiJKV1QifQ
// Get $id_token via HTTPS POST.

$client = new Google_Client(['client_id' => $CLIENT_ID]);  // Specify the CLIENT_ID of the app that accesses the backend
$payload = $client->verifyIdToken($id_token);
if ($payload) {
  $userid = $payload['sub'];
  // If request specified a G Suite domain:
  //$domain = $payload['hd'];
} else {
  // Invalid ID token
}

?>

错误信息

Parse error: syntax error, unexpected variable "$id_token" in C:\xampp\htdocs\verifier.php on line 4

解决方案

1. 修复语法错误

原代码存在两处基础语法问题:

  • 第2行$CLIENT_ID赋值末尾缺少分号;
  • 第3行$id_token的赋值语法错误,PHP中变量赋值用=而非:,且不能直接写死测试token,需从请求中获取

2. 正确获取$id_token

由于前端设置了data-ux_mode="redirect",Google登录成功后会将JWT Token以credential参数通过GET请求传递到verifier.php,因此需要从$_GET['credential']中获取。

3. 完整可运行的verifier.php代码

<?php
session_start(); // 开启session,用于存储登录用户信息
require_once 'C:\xampp\htdocs\google-api-php-client--PHP8.0\vendor\autoload.php';

$CLIENT_ID = 'xxxxx.apps.googleusercontent.com'; // 末尾添加分号

// 从GET请求中获取Google传递的JWT Token
if (!isset($_GET['credential'])) {
    // 无token,跳转回登录页
    header("Location: login.php");
    exit;
}
$id_token = $_GET['credential'];

$client = new Google_Client(['client_id' => $CLIENT_ID]);
$payload = $client->verifyIdToken($id_token);

if ($payload) {
    // 验证通过,获取用户信息
    $user_id = $payload['sub'];
    $user_email = $payload['email'];
    $user_name = $payload['name'];
    $user_domain = $payload['hd']; // 企业邮箱域名,对应前端data-hd设置

    // 验证企业域名是否匹配(可选,确保只有企业邮箱用户能登录)
    if ($user_domain !== 'xxx') { // 替换为你的企业域名
        header("Location: login.php?error=invalid_domain");
        exit;
    }

    // 将用户信息存入session,供主页面使用
    $_SESSION['logged_in'] = true;
    $_SESSION['user_name'] = $user_name;
    $_SESSION['user_email'] = $user_email;

    // 跳转至主页面
    header("Location: main.php");
    exit;
} else {
    // 验证失败,跳转回登录页并提示错误
    header("Location: login.php?error=invalid_token");
    exit;
}
?>

4. 前端代码优化建议

  • 移除重复的data-callback属性(ux_mode=redirect模式下,前端回调不会触发)
  • 统一data-locale值(当前同时设置了vi和es-419,保持一致)
  • 移除无效的redirect_uri属性(Google Sign In中应使用data-login_uri)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 08:02:34