如何集成Google一键登录?

How to integrate Google one tap sign in?

我想集成 Google Onetap 登录我的 PHP & MySQL 网站。我的代码是,这个使用 google 登录按钮的旧登录正在工作,但我不知道 google 一键登录。

    <?php //config.php

//Include Google Client Library for PHP autoload file
require_once 'vendor/autoload.php';

//Make object of Google API Client for call Google API
$google_client = new Google_Client();

//Set the OAuth 2.0 Client ID
$google_client->setClientId('xxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com');

//Set the OAuth 2.0 Client Secret key
$google_client->setClientSecret('xxxxxxxxxxxxxxxxxxxx');

//Set the OAuth 2.0 Redirect URI
$google_client->setRedirectUri('http://localhost/tutorial/php-login-using-google-demo/index.php');

//
$google_client->addScope('email');

$google_client->addScope('profile');

//start session on web page
session_start();

?>

到目前为止看起来不错,但我不建议在 public 论坛上分享您的 clientID 和 ClientSecret。

Google 提供 instructions 用于集成他们的登录服务。 我建议按照这些说明进行操作。这将需要以下文件:

  1. 包含 google 登录按钮的登录页面。您可以想象将其添加到任何现有页面。相关代码为:
<div class="g-signin2" data-longtitle="true" data-onsuccess="onSignIn"></div>
  1. 一个 javascript 文件,其中包含 onSignIn 函数和一个 signOut 函数(如果需要的话)。此文件处理重定向到成功登录页面的操作,还传递您要从用户的 Google 帐户收集的属性。我正在使用 XMLHttpRequest,但如果您愿意,可以使用 POST。此页面包含用户在成功登录后将被定向到的页面,在 xhr.onreadystatechange = function() {}:
  2. 中设置
function onSignIn(googleUser) {
  var profile = googleUser.getBasicProfile();
    var id_token = googleUser.getAuthResponse().id_token;
//    console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'includes/oauth.php');
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.onreadystatechange = function() {
        window.location = "../loggedin.php"; //Redirect to loggedin page on completion of oauth.php. Determine if new user or existing user and process accordingly
    }
    xhr.send('idtoken=' + id_token + '&googleId=' + profile.getId() + '&name=' + profile.getName() + '&imageURL=' + profile.getImageUrl() + '&email=' + profile.getEmail());
}

function signOut() {
    gapi.load('auth2', function() {
        gapi.auth2.init().then(function(){
            var auth2 = gapi.auth2.getAuthInstance();
            auth2.signOut().then(function () {
                document.location.href = 'includes/logout.php';
            });
        });
    });
}
  1. 用于处理身份验证的文件(在我上面的 javascript 文件中称为 includes/oauth.php)。注意 $leeway 的设置——这让我很伤心,因为我发现我的服务器上的时钟比 Google 授权服务器的时钟慢!:
require_once '../vendor/autoload.php';
$jwt = new \Firebase\JWT\JWT; //Allow for discrepancies between server and auth times
$jwt::$leeway = 60;

$CLIENT_ID = "ENTER_YOUR_CLIENT_ID_HERE";
$client = new Google_Client(['client_id' => $CLIENT_ID]);  // Specify the CLIENT_ID of the app that accesses the backend
$client->setRedirectUri("http://localhost/includes/oauth.php");
$client->addScope("email");
$client->addScope("profile");

if (isset($_POST['idtoken'])){
    $id_token = $_POST['idtoken'];
    $attempt = 0;
    do {
        try {
            $payload = $client->verifyIdToken($id_token);
            $retry = false;
        } catch (Firebase\JWT\BeforeValidException $e) {
            error_log("JWT server time mismatch. Retry attempt: " . strval($attempt) . "Error: " . $e, 0);
            $attempt++;
            $retry = $attempt < 3;
        }
    } while ($retry);

    if ($payload) {
      $userid = $payload['sub'];
      ...
      YOUR VALIDATION, SESSION SETTING, ETC. CODE HERE
      ...
    } else {
      // Invalid ID token
        print("Invalid ID token");
    }
} else {  //Attempt to access this page directly, redirect to Google login page
    $auth_url = $client->createAuthUrl();
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
}

  1. 登录成功后显示的页面。我在这里使用了一个插页,因为经过身份验证的用户可能是我网站的新用户并且需要创建一个配置文件,或者可能是现有用户并且想要进行他们的活动。我想验证会话是否已启动以及这是否包括成功的身份验证。