GoogleのOpenID Connectorを使ってみた
OpenID Connector の勉強のために Google の OpenID Connector を使ってみたのでメモ。
(後述するように OAuth2.0 を使ってみたという方が正しいかもしれませんが)
参考
以下の記事で Yahoo! JAPAN での例があり、まずはこちらをやってみてそれから Google でもやってみました。
また、以下についてもとても参考になりました。
やってみる
基本的なやり方は以下の Google のサイトに全部書いてあります。
なお、上記にも書いてありますが、基本的にはこれらの処理はライブラリを使ってやった方が良いかと思いますが、今回は処理の流れを理解するためにCLIやリクエストのURLを組み立てながら理解を深めます。
なお、トークン生成及びトークン確認部分はスキップしました。
必要な方はドキュメントを読んでご確認下さい。
また やってみること を目的としてそれぞれの詳細については書いてないので必要に応じてドキュメントなどを参照下さい。(というか勉強不足)
Setting up OAuth 2.0
まずはクライアントOAuth2.0の設定を行って、クライアントID、クライアントシークレットを作成します。
え、Auth2.0?と思ったのですが、Google OAuth2.0は認証・認可の両方で使用でき、OpenID Connecotorの仕様に準拠しているとの事でこちらで問題ないかと思います。
Google's OAuth 2.0 APIs can be used for both authentication and authorization. This document describes our OAuth 2.0 implementation for authentication, which conforms to the OpenID Connect specification, and is OpenID Certified
では、設定をしてみます。
- Credentils ページへGo
- 「認証情報を作成」->「OAuthクライアントIDを選択」
- 「アプリケーションの種類」では「ウェブ アプリケーション」を選択。「承認済みの JavaScript 生成元」と「承認済みのリダイレクト URI」については「http://example.com」を指定
これでクライアントID、クライアントシークレットを取得できるかとお思います。
Send an authentication request to Google
2. Send an authentication request to Google
認証リクエストを Google に送信します。
リクエスト例は以下に記載してあります。
https://accounts.google.com/o/oauth2/v2/auth?
client_id=424911365001.apps.googleusercontent.com&
response_type=code&
scope=openid%20email&
redirect_uri=https://oauth2-login-demo.example.com/code&
state=security_token%3D138r5719ru3e1%26url%3Dhttps://oauth2-login-demo.example.com/myHome&
login_hint=jsmith@example.com&
openid.realm=example.com&
hd=example.com
今回は必須パラメーターのみ指定します。
clinet_id
パラメーターは先程取得したクライアントIDを指定します。
redirect_uri
パラメーターは先程設定を行った「http://example.com」とします。
scope
及びstate
パラメーターは例と同じにします。
以下のような感じです。
https://accounts.google.com/o/oauth2/v2/auth?
client_id={client_id}&
response_type=code&
scope=openid%20email&
state=security_token%3D138r5719ru3e1%26url%3Dhttps://oauth2-login-demo.example.com/myHome&
redirect_uri=http://example.com/
これをブラウザで実行します。
すると Google のログインを要求する画面が表示されると思うのでログインします。
その後、リダイレクトURLに指定したURLに幾つかのクエリストリングが付与された形でリダイレクトされます。
例:
http://example.com/?state=security_token%3D138r5719ru3e1%26url%3Dhttps://oauth2-login-demo.example.com/myHome&code={code}&authuser=0&session_state=3905e07b81a3d9a929f5f17cc8b75a18af03a039..04b6&prompt=none#
state
はリクエスト時に指定したパラメーターと同じ値が指定されています。
code
パラメーターは one-time authorization code であり、以降の処理ではcode
パラメーターを使います。
4. Exchange code for access token and ID token
4. Exchange code for access token and ID token
code
パラメーターを使ってアクセストークン、IDトークンを取得します。
今度は GET ではなく POSTです。
ドキュメントにあるリクエスト例は以下。
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=8819981768.apps.googleusercontent.com&
client_secret={client_secret}&
redirect_uri=https://oauth2-login-demo.example.com/code&
grant_type=authorization_code
code
パラメーターは先程取得した値を指定します。
clinet_id
パラメーターは最初に取得したクライアントIDを指定します。
client_secret
パラメーターは最初に取得したクライアントシークレットを指定します。
grant_type
パラメーターは「authorization_code」を指定します。
今回はcurl
コマンドでリクエストしてみます。
$curl -H 'Content-Type:application/x-www-form-urlencoded' \
-d "code={code}&client_id={client_id}&client_secret={clinet_secret}&redirect_uri=http://example.com/&grant_type=authorization_code" \
https://www.googleapis.com/oauth2/v4/token
成功すれば以下のJSON形式のレスポンスが取得できます。
{
"access_token": "xxx",
"token_type": "Bearer",
"expires_in": 3437,
"id_token": "xxxx"
}
なお、再度同じキーを使って見ると以下のようにエラーとなります。
{
"error": "invalid_grant",
"error_description": "Code was already redeemed."
}
また、パラメーターが不正の場合には上記のようにエラーの詳細が返却されるので確認してパラメーターを修正して下さい。
5. Obtain user information from the ID token
5. Obtain user information from the ID token
ドキュメントにも書いてあるように取得した id_token はJWT (JSON Web Token)となります。
ライブラリなどでデコード出来るようですが、今回は以下のサイトにコピペしてデコードしてみます。
JWTは「ヘッダー部」、「ペイロード部」、「シグネチャー部」と別れている事が確認出来ます。
また、ペイロード部には様々な情報が記載されており、例えばEmailアドレスが確認できます。
それぞれのフィールド(claim)については 5. Obtain user information from the ID token に記載がありましたのでこちらを参照下さい。
その他JWTの詳細は別サイトなどで確認頂いた方が良さそうです。