A3L Authentication SDKの統合
このガイドでは、アプリをA3L Authentication SDKと統合する方法を説明します。
A3L Authenticationログインのセットアップ
A3L AuthenticationをAndroidアプリに統合するには、A3L Authenticationを設定し、ログインフローを開始するためのボタンを追加する必要があります。
A3L Authenticationの初期化
ログインアクティビティのonCreate()
メソッドで、Google APIコンソールから取得したAndroidクライアントIDを指定してA3L Authenticationを初期化します。以下のコードを参照してください。
<PREFIX>
には.apps.googleusercontent.com
の前のクライアントIDを指定します。Google APIコンソールからIDをコピーする場合は、.apps.googleusercontent.com
を削除してください。try{
A3LAuth.init(<PREFIX>);
} catch(APIException e) {
e.printStackTrace();
}
Google Playサービスを利用できるデバイスのデフォルトのソリューションはGoogleログインです。Google Playサービスを利用できないデバイスのデフォルトはAppAuthに設定されます。ユーザーに類似したエクスペリエンスを提供し、すべてのデバイスでAppAuthをソリューションとして使用するには、以下のコードに示すようにアプリを初期化します。
try{
A3LAuth.init(<PREFIX>, true);
} catch(APIException e) {
e.printStackTrace();
}
A3LSignInオブジェクトとA3LSignInClientオブジェクトの設定
次に、以下の手順に従ってA3LSignIn
オブジェクトとA3LSignInClient
オブジェクトを設定します。
-
onCreate()
メソッドで、A3LSignInOptions
オブジェクトを介してアプリに必要なユーザーデータをリクエストするようにA3L Authenticationを設定します。たとえば、ユーザーのIDと基本プロフィール情報をリクエストするようにA3L Authenticationを設定するには、
DEFAULT_SIGN_IN
パラメーターを使用してA3LSignInOptions
オブジェクトを作成します。ユーザーのEメールアドレスもリクエストする場合は、A3LSignInOptions
オブジェクトの作成時にrequestEmail()
オプションを含めます。以下を参照してください。// ユーザーのID、Eメールアドレス、基本プロフィールをリクエストするように // ログインを設定します。IDと基本プロフィールはDEFAULT_SIGN_INに含まれます。 A3LSignInOptions a3LSignInOptions = new A3LSignInOptions .Builder(A3LSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build();
注: アプリを意図したとおりに動作させるために追加のスコープが必要な場合は、A3LSignInOptions
オブジェクトの作成時にrequestScopes()
オプションを使用します。サポートされているスコープのリストについては、A3L Authenticationでサポートされるスコープを参照してください。 -
onCreate()
メソッドで、前の手順で作成したA3LSignInOptions
オブジェクトで指定したオプションを使用してA3LSignInClient
オブジェクトを作成します。以下のコードを参照してください。// 前述の手順で作成したA3LSignInOptionsオブジェクトで指定した // オプションを使用してA3LSignInClientを作成します。 mA3LSignInClient = A3LSignIn.getClient(this, a3LSignInOptions);
ログインしているユーザーの確認
ログインフローを表示する前に、getLastSignedInAccount()
メソッドを使用してユーザーが既にアプリにログインしているかどうかを確認します。アクティビティのonStart()
メソッドで、ユーザーが既にログインしているかどうかを確認します。以下の例を参照してください。
// 既存のログインアカウントを確認します。ユーザーが既にログインしている場合、
// A3LSignInAccountはnull以外になります。
A3LSignInAccount account = A3LSignIn.getLastSignedInAccount(this);
updateUI(account);
null以外のA3LSignInAccount
オブジェクトが返された場合、ユーザーは既にアプリにログインしているため、再度プロンプトを表示する必要はありません。アプリへのログイン後のエクスペリエンスにユーザーを進めることができます。
nullを受け取った場合は、ユーザーがアプリにログインしていないため、ユーザーがアプリにログインするためのログインボタンを提供します。
private void updateUI(A3LSignInAccount account) {
if (account!=null) {
// ログインエクスペリエンスをユーザーに提供します
} else {
// ユーザーがアプリにログインするためのボタンやその他の情報を提供します
}
}
アプリへのログインボタンの追加
アプリのカスタムログインボタンを作成できますが、Googleによって提供されているデフォルトのログインボタンを使用する場合は、以下の手順に従ってください。
-
アプリのレイアウトにログインボタンを追加します。
<com.google.android.gms.common.SignInButton android:id="@+id/sign_in_button" android:layout_width="wrap_content" android:layout_height="wrap_content" />
-
Androidアクティビティで
OnClickListener
をボタンに追加します。たとえば、onCreate()
メソッドに次のコードを追加できます。findViewById(R.id.sign_in_button).setOnClickListener(this);
ユーザーがこのボタンをクリックすると、次のセクションで説明するログインフローが開始されます。
ログインの処理
以下の手順に従ってユーザーのログインを処理します。
-
アクティビティの
onClick()
メソッドで、ユーザーがログインボタンを押したときの処理を指定します。@Override public void onClick(View v) { switch (v.getId()) { case R.id.sign_in_button: signIn(); break; // ... } }
signIn()
メソッドで、getSignInIntent()
メソッドを使用してログインインテントを作成します。以下に示すように、startActivityForResult()
メソッドでこのインテントを開始します。private void signIn() { Intent signInIntent = mA3LSignInClient.getSignInIntent(); startActivityForResult(signInIntent, RC_SIGN_IN); }
インテントの開始後に行われる処理は、アプリを実行するデバイスによって異なります。Google PlayサービスをサポートするAndroidデバイスの場合、アプリ内でログインに使用するアカウントを選択するよう求められます。Google Playサービスを使用できないデバイスの場合、アプリでカスタムタブが開き、ユーザーはGoogleの認証ウェブページにリダイレクトされます。
どちらの場合も、ユーザーはログインに使用するGoogleアカウントを選択するか、ログインに使用するEメールアドレスを入力するよう求められます。
-
onActivityResult()
メソッドでA3LSignIn.getSignedInAccountFromIntent()
メソッドを使用して、成功した場合にA3LSignInAccount
オブジェクトを返すタスクを取得します。以下を参照してください。@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // A3LSignInClient.getSignInIntent(...);からインテントを開始することで返される結果 if (requestCode == RC_SIGN_IN) { Task<A3LSignInAccount> task = A3LSignIn.getSignedInAccountFromIntent(data); handleSignInResult(task); } }
handleSignInResult()
メソッドの実装は以下のとおりです。結果のA3LSignInAccount
オブジェクトには、名前など、ログインしているユーザーに関する情報が含まれます。private void handleSignInResult(Task<A3LSignInAccount> completedTask) { completedTask.addOnCompleteListener(new OnCompleteListener<A3LSignInAccount>() { @Override public void onComplete(@NonNull Task<A3LSignInAccount> task) { try { A3LSignInAccount account = task.getResult(); updateUI(account); } catch (Exception e) { Log.e(TAG, "signInResult:failed code=" + e.getMessage()); updateUI(null); } } }); }
A3LSignInAccount
オブジェクトからユーザーデータにアクセスするには、以下のメソッドを使用します。getEmail()
:ユーザーのEメールアドレスを取得します。getId()
:クライアント側で使用するユーザーのGoogle IDを取得します。getIdToken()
:ユーザーのIDトークンを取得します。
現在ログインしているユーザーをバックエンドサーバーに渡すには、IDトークンをバックエンドサーバーに送信し、サーバー上でトークンを検証します。
ユーザープロフィール情報へのアクセス
A3LSignInオブジェクトとA3LSignInClientオブジェクトの設定でA3LSignInOptions
オブジェクトをどのように設定したかに応じて、ログインしているユーザーのどの情報にアクセスできるかが決まります。A3LSignInOptions
を設定するときにDEFAULT_SIGN_IN
パラメーターまたはrequestProfile()
メソッドを使用した場合は、ログイン後にユーザーの基本プロフィール情報にアクセスできます。A3LSignInOptions
を設定するときにrequestEmail()
メソッドを使用した場合は、ユーザーのEメールアドレスにもアクセスできます。
現在ログインしているユーザーのプロフィール情報をリクエストするには、A3LSignIn.getLastSignedInAccount()
メソッドを使用します。以下の例を参照してください。
A3LSignInAccount acct = A3LSignIn.getLastSignedInAccount(getActivity());
if (acct != null) {
String personName = acct.getDisplayName();
String personGivenName = acct.getGivenName();
String personFamilyName = acct.getFamilyName();
String personEmail = acct.getEmail();
String personId = acct.getId();
Uri personPhoto = acct.getPhotoUrl();
}
A3LSignInAccount
オブジェクトからアクセスできる可能性のあるすべてのフィールドについては、A3L Authentication APIリファレンスを参照してください。
ユーザーのログアウト
ログアウトボタンを追加することで、ユーザーがアプリからログアウトできるようになります。ログアウトボタンを作成したら、OnClickListener
をそのボタンにアタッチして、signOut()
メソッドを呼び出すようにonClick()
メソッドを設定します。以下のコードを参照してください。
@Override
public void onClick(View v) {
switch (v.getId()) {
// ...
case R.id.button_sign_out:
signOut();
break;
// ...
}
}
private void signOut() {
mA3LSignInClient.signOut()
.addOnCompleteListener(this, new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
// ...
}
});
}
アプリがこのコードを実行すると、ユーザーのGoogleアカウントがアプリからログアウトされます。ユーザーはGoogleアカウントを使用して再度ログインすることもできます。その際、特定のスコープへのアクセスのリクエストなど、権限を求めるプロンプトが表示されることはありません。
アカウントの解除
ユーザーはアプリからGoogleアカウントを解除できます。ユーザーがアプリからアカウントを解除することを選択した場合、アプリがGoogleのAPIから取得した情報を削除する必要があります。アクセスを取り消すと、スコープを介して自分のデータにアクセスできるようユーザーがアプリに付与した権限が削除されます。
ユーザーのアカウントを解除するには、revokeAccess()
メソッドを呼び出します。以下の例を参照してください。
private void revokeAccess() {
mA3LSignInClient.revokeAccess()
.addOnCompleteListener(this, new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
// ...
}
});
}
OnCompleteListener
で、アプリはイベントに応答し、必要なコードを追加で実行できます。
A3L Authenticationにはアプリのアクセスの取り消し機能がありますが、それはGoogleのアクセスの取り消し機能とは異なります。Googleログインを使用してアクセスを取り消すと、ユーザーのGoogleアカウントからアプリが削除されます。この動作はA3L Authenticationには該当しません。A3L Authenticationでは、アクセスの取り消し機能によってアプリからユーザーのアクセスが取り消され、アプリに付与されたデータへのアクセス権限が削除されますが、ユーザーのアカウントのエントリは削除されません。エントリからアプリを削除するには、Google開発者向けドキュメントの取り消し方法を参照してください。
バックエンドサーバーでの認証
A3L Authenticationを使用していて、アプリがバックエンドサーバーと通信する場合、現在ログインしているサーバー上のユーザーを特定する必要がある可能性があります。現在ログインしているユーザーを安全に特定するには、HTTPSを使用してユーザーのIDトークンをサーバーに送信します。サーバーでIDトークンの整合性を確認してください。トークンのユーザーデータを使用して、既知のユーザーとのセッションを確立するか、新しいユーザーの新しいアカウントレコードを作成します。
IDトークンの取得
まず、ログイン時にユーザーのIDトークンを取得する必要があります。requestIdToken()
メソッドを使用してA3L Authenticationを設定し、サーバーのウェブクライアントIDをこのメソッドに渡します。以下を参照してください。
// ユーザーのIDトークンのみをリクエストします。
// これによりバックエンドでユーザーを安全に特定できます。これにはユーザーの基本プロフィール
//(名前、プロフィール写真のURLなど)が含まれるため、アプリをパーソナライズするために
// 追加の呼び出しを行う必要はありません。
A3LSignInOptions a3LSignInOptions = new A3LSignInOptions.Builder(A3LSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.server_client_id))
.requestEmail()
.build();
ユーザーのログイン時に、ログインインテントのアクティビティ結果からA3LSignInAccount
オブジェクトを取得します。
Task<A3LSignInAccount> task = A3LSignIn.getSignedInAccountFromIntent(data);
handleSignInResult(task);
ユーザーがログインしたら、以下のようにA3LSignInAccount
オブジェクトからIDトークンを取得します。
private void handleSignInResult(@NonNull Task<A3LSignInAccount> completedTask) {
completedTask.addOnCompleteListener(new OnCompleteListener<A3LSignInAccount>() {
@Override
public void onComplete(@NonNull Task<A3LSignInAccount> task) {
try {
A3LSignInAccount account = task.getResult();
String idToken = account.getIdToken();
// IDトークンを処理
} catch (Exception e) {
Log.w(TAG, "signInResult:failed code=" + e.getMessage());
updateUI(null);
}
}
});
}
サーバーへのIDトークンの送信
以下のように、HTTPS POSTリクエストを使用してIDトークンをサーバーに送信します。
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("https://yourbackend.example.com/tokensignin");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("idToken", idToken));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpPost);
int statusCode = response.getStatusLine().getStatusCode();
final String responseBody = EntityUtils.toString(response.getEntity());
Log.i(TAG, "Signed in as: " + responseBody);
} catch (ClientProtocolException e) {
Log.e(TAG, "Error sending ID token to backend.", e);
} catch (IOException e) {
Log.e(TAG, "Error sending ID token to backend.", e);
}
Google開発者向けドキュメントのIDトークンの整合性を確認するの手順に従って、取得したIDトークンを検証します。
関連トピック
Last updated: 2023年12月5日