Webサイトにグーグルアカウントでログインする機能を実装する[実装編]
ウェブサイトにグーグルアカウントでのログイン機能「Google Sign-In」を実装する、
の「実装編」です
前回の準備編はこちらです
概要
簡単に概要を説明します
今回の実装に登場するのは以下の2ファイルです
- login.html ← ログインボタンがあるページ
- server-side.php ← ユーザ情報を取得して登録処理などをするサーバ側のPHPファイル
ユーザはログインページであるlogin.html内のグーグルログインボタンを押してアカウントを選択します
そのデータを取得したサーバ側のserver-side.phpで、登録処理なんかをします
Google Sign-Inの実装
1. クライアントIDの定義
login.html
<head>
<meta name="google-signin-client_id" content="準備編で取得したクライアントID">
</head>
準備編で取得したクライアントIDをMetaタグで定義します
Metaタグなので、HTMLのheadタグの間に書きます
2. Google Platformライブラリのロード
login.html
<script src="https://apis.google.com/js/platform.js" async defer></script>
JavascriptでGoogle Platform Libraryをロードします
3. 「グーグルでログインする」ボタンの設置
ログインボタンをHTMLで設置します
login.html
<div class="g-signin2" data-onsuccess="onSignIn"></div>
オプション
ダークモード
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
data-theme="dark"を設定すると見た目が変わります(全然ダークじゃないけど)
オフライン
<div class="g-signin2"
data-onsuccess="onSignIn"
data-scope="https://www.googleapis.com/auth/plus.login"
data-accesstype="offline"
data-redirecturi="https://example.com/redirect-path"></div>
data-accesstypeでofflineを指定すると、通常のポップアップでのアカウント選択画面ではなく、画面遷移型に切り替えることができます
4. プロフィール情報の取得
login.html
<script>
function onSignIn(googleUser) {
// プロフィールの取得
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId());// このIDをサーバに送ってはいけない
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
// トークンの取得(サーバーにはこちらを送信)
var id_token = googleUser.getAuthResponse().id_token;
console.log('token: ' + token);
}
</script>
3で設置したボタンを押下すると、このコールバックが呼び出されます
ここでユーザのプロフィール情報が取得できます、が、
ここで必要なのはトークンだけです
公式ドキュメントにも書いてありますが、profile.getId()で取得できるIDをサーバに送ってはいけません
サーバに送るのはgoogleUser.getAuthResponse().id_tokenで取得したトークンのみです
(ここで取得できる名前やメールアドレスは、サーバ側でも別途取得できます)
5. サーバへ送信
4で取得したトークンを、サーバへ送信します
login.html
<script>
function onSignIn(googleUser) {
// トークンの取得(サーバーにはこちらを送信)
var id_token = googleUser.getAuthResponse().id_token;
// 接続を解除して、2回目以降の自動ログインを防止
var auth2 = gapi.auth2.getAuthInstance();
auth2.disconnect();
// 5.サーバへ送信
var xhr = new XMLHttpRequest();
// open()で指定するのは、サーバ側のURL
xhr.open('POST', 'https://example.com/server-side.php');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 処理が終わった後に呼ばれるコールバック
xhr.onload = function() {
if(xhr.readyState == 4 && xhr.status == 200 && response){
// ログイン完了後にリダイレクト
window.location.href = 'https://example.com';
}
else{
console.log('エラー');
}
};
xhr.send('idtoken=' + id_token);
}
</script>
次の6の処理が正常に終了すると、xhr.onloadで指定したfunction()が呼ばれます
その中で、ログインした後に表示したいページへリダイレクトします(上の例ではhttps://example.com)
6.サーバ側の処理
5で送信したユーザ情報を、サーバ側で受け取ります
server-side.php
require_once 'vendor/autoload.php';
// POSTで送られてくるトークンを取得.
$id_token = filter_input(INPUT_POST, 'idtoken');
$client = new Google_Client(['client_id' => '準備編で取得したクライアントID']);
$payload = $client->verifyIdToken($id_token);
if ($payload) {
$userid = $payload['sub'];
// ユーザ登録やログイン処理など
// 結果を出力
echo $userid;
} else {
// Invalid ID token
// 結果を出力
echo null;
}
ユーザを識別するIDにはpayloadのsubを利用します
メールアドレスは変更される可能性があるのでユーザの識別に利用してはいけません
成功するとpayloadには以下のような情報がセットされます
(
[iss] => accounts.google.com
[azp] => 0123456789.apps.googleusercontent.com
[aud] => 0123456789.apps.googleusercontent.com
[sub] => 1234567890123456789
[email] =>accounts@mail.com
[email_verified] => 1
[at_hash] => lkejfaiowef__fsdlDFJf
[name] => Boku No Namae
[picture] => https://lh3.googleusercontent.com/0123456789
[given_name] => Boku
[family_name] => Namae
[locale] => ja
[iat] => 1523456789
[exp] => 1534567890
[jti] => 23kljfewlklkj32jf2i3jfl2kjfsdklfjs
)
処理が終わったら、5のJavascriptで定義したxhr.onloadへ返却するためのパラメーターを出力(echo)します
ディスカッション
コメント一覧
まだ、コメントがありません
新たにPostされたDocs
: ツール関連
キーボードを銀軸から赤軸に買い替えた話
約3年半前、仕事で使うキーボードとしてARCHISS ProgresTouchの ...: スマホ
楽天モバイルがおすすめできない人の特徴とは?
楽天モバイルの最強プランをおすすめできない人の特徴を簡単にまとめてみました また ...: システム開発
なぜスクラムがつらいのか?開発現場が疲弊するのか?スクラムに対する違和感と共に原因を考えてみた
今ではどこの開発現場に行っても、やれスクラムスクラムと、まるでスクラムでもやって ...: Laravel
1つのテーブルを複数のテーブルと結合したい【Laravel10】
1つのテーブルを2つの異なるテーブルに対して結合したいケースがあったのでLara ...: Laravel
Laravelで複数画像アップロード時のvalidateを指定【Laravel10】
jQuery - Image Uploaderを使って、フォームから複数の画像を ...HashMap
created_by
はやぴ
Web/アプリ開発エンジニア
Sierにてお堅いB向けのソフトウェア開発を経て、現在はC向けのWebやアプリを中心に開発しています。
Utilities