今回は、Googleログイン認証を実装するメモとなります。
Googleログインは、以前はGoogle Identity Platformでの実装方法がありましたが、
2023年3月31日以降非推奨になったようです。
<!-- 2023/3/31以降非推奨 -->
<script src="https://apis.google.com/js/platform.js" async defer></script>
その為、今回のメモでは新しいGoogle Identity Servicesを利用した内容となります。
以下が公式のドキュメントとなります。
https://developers.google.com/identity/gsi/web/guides/display-button?hl=ja&authuser=1
目次
Google Colud プロジェクト設定
以前のGoogle Identity Platformの時と同様にプロジェクト設定を行います。
プロジェクト作成
Google Cloud Consoleを開き、プロジェクト選択部分からプロジェクト新規作成を行います。
OAuth 同意画面 設定
続けてOAuth 同意画面の設定を行います。
必須項目を入力して、登録します。
テストユーザーなども必要に応じて登録します。
OAuth クライアントID 準備
・OAuth クライアントID 作成
・リクエストURI・リダイレクトURI設定
クライアントID作成時に、Googleログインボタンを配置して認証処理を行うエンドポイントと、
認証後にリダイレクトさせたいエンドポイントを設定します。
ここではローカルで確認したいエンドポイントで設定しました。
・OAuthクライアントID確認
作成されたクライアントIDとクライアントシークレットが表示されたら、内容を控えます。
Google認証ボタン 実装
確認用にローカルで簡単なhttpサーバーを起動します。
以下はSpringBootのコードで試していますが、特に意味はありません。
@RestController
public class GoogleOauthSampleController {
// Googleログインボタン確認用のサンプル画面表示
@RequestMapping(path = "/", method = RequestMethod.GET)
public ModelAndView index(final ModelAndView mav) {
mav.setViewName("index"); // テンプレートHTML指定
return mav;
}
}
Googleログイン画面 ポップアップ表示
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Google認証サンプル</h1>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<div id="g_id_onload"
data-client_id="生成済みクライアントID"
data-size="small"
data-callback="loginCallback"></div>
<div class="g_id_signin" data-type="standard"></div>
<script>
// ログイン後のユーザー情報確認用デバッグコードです。
// ログイン処理後に実行したいJavaScript
// function名を、data-callback="function名"で指定できます。
function loginCallback(e) {
const data = decode(e.credential);
console.log(`ID: ${data.sub}`);
console.log(`Full Name: ${data.name}`);
console.log(`Given Name: ${data.given_name}`);
console.log(`Family Name: ${data.family_name}`);
console.log(`Image URL: ${data.picture}`);
console.log(`Email: ${data.email}`);
}
function decode(jwt) {
const base64Url = jwt.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const str1 = atob(base64);
const str2 = escape(str1);
const str3 = decodeURIComponent(str2);
return JSON.parse(str3);
}
</script>
</body>
</html>
Googleログインボタンのデザイン調整などは、cssで調整できますが、
タグに指定できる公式の属性でもある程度調整できます。詳しくは以下を参考にして下さい。
Googleログインボタンをクリックすると、
ポップアップ形式でGoogleログイン画面が表示されます。
メールアドレスを入力して認証を行います。
Googleアカウントの設定次第で、2段階認証などを求められるので、全て処理をします。
ログイン後はボタンの表示が変化して、ログインしたGoogleアカウントの情報が表示されます。
F12キーなどを押して、ブラウザの開発者ツールのConsoleを確認すると、
デバッグコードの実行結果が表示され、ログイン者情報が確認できます。
Googleログイン画面 リダイレクト表示
ログイン画面は、ポップアップ表示せずそのままの画面に表示させ、
ログイン認証後、リダイレクト処理を行うこともできます。
こちらのパターンもメモさせて頂きます。
リダイレクト形式にする場合、以下の属性をid=”g_id_onload”のdivタグに追加します。
data-ux_mode="redirect"
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Google認証サンプル</h1>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<!-- リダイレクトにすると、こちらのHtmlで表示されている画面では、
data-callbackで、ログイン者情報を受け取れません -->
<div id="g_id_onload"
data-client_id="生成済みクライアントID"
data-ux_mode="redirect"
data-login_uri="リダイレクトしたいエンドポイント"
data-size="small"></div>
<div class="g_id_signin" data-type="standard"></div>
</body>
</html>
認証後、data-login_uriで指定されたエンドポイントに以下のパラメータがPOST送信されます。
形式 | Name | 説明 |
---|---|---|
cookie | g_ |
ハンドラ エンドポイントへのリクエストごとに変化するランダムな文字列。 |
リクエスト パラメータ | g_ |
前の Cookie の値(g_ )と同じ文字列 |
リクエスト パラメータ | credential |
Google が発行する ID トークン。 |
リクエスト パラメータ | select_ |
認証情報の選択方法 |
credentialの内容をデコードすると以下の内容が得られます。
認証されたアカウントの情報(メールアドレス、名前など)がパラメータに含まれています。
header {
"alg": "RS256",
"kid": "f05415b13acb9590f70df862765c655f5a7a019e", // JWT signature
"typ": "JWT"
}
payload {
"iss": "https://accounts.google.com", // The JWT's issuer
"nbf": 161803398874,
"aud": "314159265-pi.apps.googleusercontent.com", // Your server's client ID
"sub": "3141592653589793238", // The unique ID of the user's Google Account
"hd": "gmail.com", // If present, the host domain of the user's GSuite email address
"email": "elisa.g.beckett@gmail.com", // The user's email address
"email_verified": true, // true, if Google has verified the email address
"azp": "314159265-pi.apps.googleusercontent.com",
"name": "Elisa Beckett", // If present, a URL to user's profile picture
"picture": "https://lh3.googleusercontent.com/a-/e2718281828459045235360uler",
"given_name": "Eliza", "family_name": "Beckett",
"iat": 1596474000, // Unix timestamp of the assertion's creation time
"exp": 1596477600, // Unix timestamp of the assertion's expiration time
"jti": "abc161803398874def"
}
credentialのデコードは、以下のページで行えます。
また、プログラミング言語でデコードする場合、言語毎に用意されているデコード用ライブラリを利用して行います。
Using a Google API Client Library
詳細は、以下の公式ドキュメントをご確認ください。
https://developers.google.com/identity/gsi/web/reference/html-reference?authuser=1&hl=ja#server-side
Java(SpringBoot)での実装サンプルもメモしてみましたので、
よろしければ参考に頂ければと思います。
今回のメモは以上となります。
Googleログインボタンは、フロントエンドはタグの設置だけで済むので簡単に実装できます。
ただし、JavaScriptで認証後の情報を処理したり、サーバーサイド側で情報を扱う場合には、
色々とセキュリティ面を考慮する必要が出てきますので、
注意して実装頂ければと思います。