インターネットに接続されたテレビなど、入力機能が制限されているデバイスで、ユーザーが自分のGoogleアカウントを使用してアプリにサインインできるようにすることができます。
アプリは、ユーザーに短いコードとサインインURLを表示します。次に、ユーザーはWebブラウザーでサインインURLを開き、コードを入力して、ユーザーのサインイン情報にアクセスするためのアクセス許可をアプリに付与します。最後に、アプリは確認を受け取り、ユーザーはサインインします。
このサインインフローを使用するには、アプリが次の条件を満たすデバイスで実行されている必要があります。
- デバイスは、ユーザーへの指示とともに、40文字のURLと15文字のユーザーコードを表示できる必要があります。
- デバイスはインターネットに接続されている必要があります。
クライアントIDとクライアントシークレットを取得する
Googleのサインインエンドポイントにリクエストを送信するには、アプリにOAuth2.0クライアントIDとクライアントシークレットが必要です。
プロジェクトのクライアントIDとクライアントシークレットを見つけるには、次の手順を実行します。
- 既存のOAuth2.0資格情報を選択するか、[資格情報]ページを開きます。
- まだ作成していない場合は、[資格の作成]> [OAuthクライアントID ]をクリックし、資格の作成に必要な情報を入力して、プロジェクトのOAuth2.0資格を作成します。
- OAuth2.0クライアントIDセクションでクライアントIDを探します。詳しくは、クライアントIDをクリックしてください。
新しいクライアントIDを作成する場合は、 TVおよび制限付き入力デバイスのアプリケーションタイプを選択します。
ユーザーコードと確認URLを取得する
ユーザーがGoogleアカウントを使用してサインインをリクエストすると、HTTP POSTリクエストをOAuth2.0デバイスエンドポイントhttps://oauth2.googleapis.com/device/code
に送信して、ユーザーコードと確認URLを取得します。クライアントIDと必要なスコープのリストをリクエストに含めます。 Googleアカウントでユーザーにログインするだけの場合は、 profile
とemail
スコープのみをリクエストしてください。または、ユーザーに代わってサポートされているAPIを呼び出す許可を要求する場合は、 profile
とemail
のスコープに加えて、必要なスコープを要求します。
以下は、ユーザーコードのリクエスト例です。
POST /device/code HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=CLIENT_ID&scope=email%20profile
curl
使用:
curl -d "client_id=CLIENT_ID&scope=email profile" https://oauth2.googleapis.com/device/code
応答はJSONオブジェクトとして返されます。
{
"device_code" : "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
"user_code" : "GQVQ-JKEC",
"verification_url" : "https://www.google.com/device",
"expires_in" : 1800,
"interval" : 5
}
アプリはuser_code
とverification_url
の値をユーザーに表示すると同時に、ユーザーがサインインするか、 expires_in
で指定された時間が経過するまで、指定されたinterval
でサインインエンドポイントをポーリングします。
ユーザーコードと確認URLを表示する
デバイスエンドポイントからユーザーコードと確認URLを受け取ったら、それらを表示し、URLを開いてユーザーコードを入力するようにユーザーに指示します。
verification_url
とuser_code
の値は変更される可能性があります。次の制限を処理できるようにUIを設計します。
-
user_code
は、W
サイズの文字を処理するのに十分な幅のフィールドに表示する必要があります。 -
verification_url
は、40文字の長さのURL文字列を処理するのに十分な幅のフィールドに表示する必要があります。
どちらの文字列にも、US-ASCII文字セットの印刷可能な文字を含めることができます。
user_code
文字列を表示するときは、文字列を変更しないでください(大文字と小文字の変更や他の書式設定文字の挿入など)。将来、コードの形式が変更された場合にアプリが破損する可能性があります。
必要に応じて、表示目的でURLからスキームを削除することにより、 verification_url
文字列を変更できます。その場合は、アプリが「http」と「https」の両方のバリエーションを処理できることを確認してください。それ以外の場合は、 verification_url
文字列を変更しないでください。
ユーザーが確認URLに移動すると、次のようなページが表示されます。
ユーザーがユーザーコードを入力すると、Googleサインインサイトに次のような同意画面が表示されます。
ユーザーが[許可]をクリックすると、アプリはユーザーを識別するためのIDトークン、Google APIを呼び出すためのアクセストークン、および新しいトークンを取得するための更新トークンを取得できます。
IDトークンを取得してトークンを更新する
アプリにユーザーコードと確認URLが表示されたら、デバイスエンドポイントから受け取ったデバイスコードを使用してトークンエンドポイント( https://oauth2.googleapis.com/token
)のポーリングを開始します。 interval
値で指定された間隔(秒単位)でトークンエンドポイントをポーリングします。
以下はリクエストの例です。
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=CLIENT_ID&client_secret=CLIENT_SECRET&code=DEVICE_CODE&grant_type=http://oauth.net/grant_type/device/1.0
curl
使用:
curl -d "client_id=CLIENT_ID&client_secret=CLIENT_SECRET&code=DEVICE_CODE&grant_type=http://oauth.net/grant_type/device/1.0" https://oauth2.googleapis.com/token
ユーザーがまだリクエストを承認していない場合、応答は次のようになります。
{
"error" : "authorization_pending"
}
アプリは、 interval
の値を超えない速度でこれらの要求を繰り返す必要があります。アプリのポーリングが速すぎる場合、応答は次のようになります。
{
"error" : "slow_down"
}
ユーザーがサインインして、要求したスコープへのアクセスをアプリに許可すると、アプリの次の要求への応答には、IDトークン、アクセストークン、および更新トークンが含まれます。
{
"access_token" : "ya29.AHES6ZSuY8f6WFLswSv0HZLP2J4cCvFSj-8GiZM0Pr6cgXU",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/551G1yXUqgkDGnkfFk6ZbjMMMDIMxo3JFc8lY8CAR-Q",
"id_token": "eyJhbGciOiJSUzI..."
}
この応答を受信すると、アプリはIDトークンをデコードして、サインインしたユーザーに関する基本的なプロファイル情報を取得したり、IDトークンをアプリのバックエンドサーバーに送信してサーバーで安全に認証したりできます。また、アプリはアクセストークンを使用して、ユーザーが承認したGoogleAPIを呼び出すことができます。
IDトークンとアクセストークンの有効期間は限られています。トークンの有効期間を超えてユーザーがサインインし続けるには、更新トークンを保存し、それを使用して新しいトークンを要求します。
IDトークンからユーザープロファイル情報を取得する
JWTデコードライブラリを使用してIDトークンをデコードすることにより、サインインしたユーザーに関するプロファイル情報を取得できます。たとえば、Auth0 jwt- decodeJavaScriptライブラリを使用します。
var user_profile = jwt_decode(id_token); // The "sub" field is available on all ID tokens. This value is unique for each // Google account and can be used to identify the user. (But do not send this // value to your server; instead, send the whole ID token so its authenticity // can be verified.) var user_id = user_profile["sub"]; // These values are available when you request the "profile" and "email" scopes. var user_email = user_profile["email"]; var email_verified = user_profile["email_verified"]; var user_name = user_profile["name"]; var user_photo_url = user_profile["picture"]; var user_given_name = user_profile["given_name"]; var user_family_name = user_profile["family_name"]; var user_locale = user_profile["locale"];
詳しくは
- IDトークンの有効期間を超えてユーザーがサインインし続けるには、「アクセストークンの更新」を参照してください。
- バックエンドサーバーで認証する必要がある場合は、安全に行う方法について、「バックエンドサーバーで認証する」を参照してください。