PHPでGoogleログイン
PHPでGoogleログインを実装する。
使用環境
・ PHP 8.2.9
・ google/apiclient (Composerでインストール)
手順の概要
- GCP(Google Cloud Platform)にプロジェクトを作成する
- OAuth同意画面を設定する
- 認証情報(OAuth2.0クライアントID)を登録する
- ログイン画面を用意する(SSL通信、及び、ドメインが必要 ※ドメインはlocalhost可)
- ログイン結果を受け取るPHPスクリプトを用意する
GCPにプロジェクトを作成する
GCP(Google Cloud Platform)にログインして、プロジェクトの選択プルダウンをクリック。
ダイアログが開いたら、「新しいプロジェクト」をクリック。
プロジェクト名を入力して「作成」を実行。
下図では例として「LoginSample」と入力。
OAuth同意画面を設定する
左上のハンバーガーメニューを開き、「APIとサービス」を選択。
続けて、「OAuth同意画面」を選択。
OAuth同意画面の設定画面が開いたら、User Type「外部」を選択して「作成」を実行。
続く設定画面にて、アプリ名、ユーザーサポートメール、デベロッパーの連絡先情報を入力する。
(他項目は任意なので必要に応じて設定)
入力したら「保存して次へ」を実行。
次の設定画面で、スコープを追加する。
まずは、「スコープを追加または削除」ボタンをクリックする。
開いた画面で、以下3つのスコープを選択して「更新」を実行。
元の画面に戻るので、「非機密のスコープ」に選択した3つが追加されていることを確認して「保存して次へ」。
続けてテストユーザーの設定画面に進むが、登録は不要。
そのまま「保存して次へ」を実行。
※以上で同意画面の設定は完了するが、公開ステータスがデフォルトで「テスト」になっている。
本番利用する際は、これを「本番環境」に切り替える必要があるので注意。
認証情報を登録する
登録と言っているが、認証情報(OAuth2.0クライアントID)を作成・取得するのがゴール。
左上のハンバーガーメニューを開き、「APIとサービス」を選択。
続けて、「OAuth同意画面」を選択。
認証情報画面が開いたら、上部の「+認証情報を作成」内の「OAuthクライアントID」を選択。
作成画面が開いたら、以下を設定する。
アプリケーションの種類は「ウェブアプリケーション」を選択。
名前は識別用なので任意の名前を入力。
承認済みのJavaScript生成元のURIには、ログイン画面を設置するURIを設定する。
その際、「https://」が必須(http://で指定すると、後々ログイン画面でJavaScriptがエラーを吐く)。
また、IPでは指定出来ずドメインが必要(localhostは可)。
必要に応じてポート番号の指定まで指定。
ドメイン以下(例えば、login.phpなど)は不要。
承認済みのリダイレクトURIには、ログイン後の遷移先のURLを指定する。
こちらはドメイン以降も入力が必要。
ただし、今回の実装方法ではログイン画面でリダイレクト先URLを指定するので設定しなくても動く。
各設定が終わったら「作成」を実行。
作成が終わるとクライアントIDが発行されるので、これを控えておく。
(控えずに画面を閉じてしまった場合、後からでも画面を開けば確認出来る)
ログイン画面を用意する
ログイン画面用のHTMLファイルを用意し、WEBサーバに設置する。
※OAuthクライアントID発行の際に設定した「承認済みのJavaScript生成元」とログイン画面のURLが一致する必要があるので注意。
<html lang="ja">
<head></head>
<body>
<script src="https://accounts.google.com/gsi/client" async></script>
<div id="g_id_onload"
data-client_id="[前項で控えたクライアントID]"
data-context="signin"
data-ux_mode="popup"
data-login_uri="https://localhost:8888/auth.php"
data-auto_prompt="false">
</div>
<div class="g_id_signin"
data-type="standard"
data-shape="pill"
data-theme="outline"
data-text="signin_with"
data-size="large"
data-logo_alignment="left">
</div>
</body>
</html>
login.html必要なJSファイルはGoogle社が提供しているので、それを読み込む。(5行目)
ボタンの表示には上記2つの<div>を置くが、パラーメータの内2つは指定が必要。
data-client_idには、前項で控えたクライアントIDを記載する。
data-login_uriには、OAuthクライアントIDを発行する際に登録したリダイレクトURIを記載する。
(GCP側の設定ではなく、こちらの指定が実際使われる。なので、GCP側の設定は省略していても問題はない)
その他のパラメータはボタンの見た目など。
Googleが提供しているツールでHTMLを生成出来るので、こちらを使って取得したHTMLを貼るのが良い。
https://developers.google.com/identity/gsi/web/tools/configurator?hl=ja
ログイン画面を実際に開くと、下図のようなボタンが表示される。
※ボタンを表示した際にエラーが出ていないかブラウザの開発ツールで確認しておくこと。
見た目上ボタンが出ているが、裏でエラーが出ていることがある。
・SSL通信になっていない
・ログイン画面のURLがOAuthクライアントIDを発行する際に登録したリダイレクトURIと一致しない
・パラメータ等に不備がある
などが考えられる。
ログインのリダイレクト先を用意する
ログイン成功時のリダイレクト先を用意する。
ここはPHPで実装。
事前準備として、google/apiclientをComposerでインストールする。
composer require google/apiclient
ログイン結果を受け取るスクリプト例は以下のようなもの。
<?php
require_once '../vendor/autoload.php';
$idToken = $_POST['credential'];
define( 'CLIENT_ID', '[前項で控えたクライアントID]' );
$client = new Google_Client( [ 'client_id' => CLIENT_ID ] );
$payload = $client->verifyIdToken( $idToken );
if ( $payload ) {
var_dump( $payload );
} else {
// Error
}
auth.phpGoogle認証が通ると、リダイレクト先に対してIDトークンがPOSTで送られてくる。
それとIDトークンを使ってユーザ情報を取得する。
上記で$payloadに含まれる情報は連想配列で以下のようになっている。
iss | トークンの発行者(または署名者)。 https://accounts.google.com で固定。 |
azp | トークンの発行者。クライアントIDが入る。 |
aud | トークンの対象。クライアントIDが入る。 |
sub | GoogleアカウントのユニークなID |
Emailアドレス | |
email_verified | Emailの正誤確認。Googleの場合、true固定? |
nbf | nbf = not before。JWT が有効になるUnixエポック時刻 |
name | Googleアカウントのユーザ名(姓+名) |
picture | Googleアカウントのアイコン画像 |
given_name | Googleアカウントのユーザ名(名) |
family_name | Googleアカウントのユーザ名(姓) |
iat | トークンが発行されたUnixエポック時刻 |
exp | トークンの有効期限が切れるUnixエポック時刻 |
jti | Googleログインごとに生成される一意のID |
パラメータを受け取った後の処理としては、sub、email、name、picture、given_name、family_nameを使って初回ログイン時のユーザ登録を。
2回目以降のログインでは、subを使ってユーザを特定、認証する。
など。