このページの手順に従って、now.ggログインをAndroidアプリに統合、設定し、ログインフローを開始するnow.ggサインインボタンをアプリのレイアウトに追加してください。
必須要項のチェックリストと開発環境のセットアップが完了していることを確認してください。
まず、AndroidManifest.xmlに権限を追加します。
<uses-permission android:name="android.permission.GET_ACCOUNTS"/> <uses-permission android:name="android.permission.INTERNET"/>
次の依存関係をアプリケーションの build.gradle ファイルに追加してください:
//retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0' implementation 'com.squareup.retrofit2:converter-scalars:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
now.ggサインインボタンのアセットは、now.gg SDKパッケージのAssets/Loginディレクトリに含まれています。
Button signInButton = findViewById(R.id.now_gg_login_button);
Android アクティビティの onCreate メソッドに、サインイン ボタンの OnClickListener を追加します。
findViewById(R.id.now_gg_login_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
signIn();
}
});
次に、GET_ACCOUNTS 権限と結果を確認してください。
GET_ACCOUNTS許可を確認するには、onCreateメソッドに以下のコードを追加します。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkSelfPermission(Manifest.permission.GET_ACCOUNTS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {
Manifest.permission.GET_ACCOUNTS
},
GET_ACCOUNTS_REQUEST_CODE);
} else {
// has GET_ACCOUNTS permission, can proceed with signin
Log.d(TAG, "onCreate: Already has permission, proceed with signin");
}
}
onRequestPermissionsResultに以下のコードを追加します。
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == GET_ACCOUNTS_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted, can proceed with sign-in.
signIn();
}
}
}
次のコードサンプルは「now.gg アカウントでサインインする」ためのものです。ログインボタンをクリックするとトリガーされるべきです。
public static final String ID_TOKEN = "id_token"; // Do Not Modify
public static final String CLIENT_ID = "<your client id>"; // Replace with your client id
public static final String ACCOUNT_TYPE = "now.gg"; // Do Not Modify
public static final String HOST_URL = "hostUrl"; //Do Not Modify
private void signIn() {
Account account = getNowggAccount();
if (account != null) {
Bundle bundle = new Bundle();
bundle.putString("client_id", CLIENT_ID);
String authTokenType = ID_TOKEN;
AccountManager.get(getApplicationContext()).
getAuthToken(account, authTokenType, bundle, MainActivity.this, new OnTokenAcquired(), null);
} else {
addNowggAccount();
}
}
private Account getNowggAccount() {
Account[] accounts = AccountManager.get(getApplicationContext()).getAccountsByType(ACCOUNT_TYPE);
if (accounts.length > 0) {
Log.d(TAG, "getNowggAccount: account found");
// currently only one now.gg account can be added in a system
return accounts[0];
}
return null;
}
private void addNowggAccount() {
try {
Intent intent = new Intent();
intent.setComponent(new ComponentName("gg.now.accounts", "gg.now.accounts.AuthenticatorActivity"));
intent.setAction("IAP_ADD_ACCOUNT");
intent.putExtra("resultReceiver", parcelResultReceiver(resultReceiver));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
}
ResultReceiver parcelResultReceiver(ResultReceiver actualReceiver) {
Parcel parcel = Parcel.obtain();
actualReceiver.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
parcel.recycle();
return receiverForSending;
}
ResultReceiver resultReceiver = new ResultReceiver(new Handler(Looper.getMainLooper())) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
Log.d(TAG, "onReceiveResult() called with: resultCode = [" + resultCode + "], resultData = [" + resultData.toString() + "]");
// onReceiveResult
if (resultCode == 0) { // means sign in is okay
signIn();
} else {
// sign in failed
Log.d(TAG, "onReceiveResult: sign in failed");
}
}
};
ユーザーがサインインした後、OnTokenAcquired コールバック関数でリクエストされたトークン (id_token) を取得します。
このトークンは、トークンを検証するか、トークンをバックエンドサーバーに渡してユーザーの詳細を取得するために使用できます。サーバーから応答としてユーザーの詳細を取得できます。
private class OnTokenAcquired implements AccountManagerCallback {
@Override
public void run(AccountManagerFuture result) {
try {
Bundle bundle = (Bundle) result.getResult();
boolean success = bundle.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
if (success) {
final String token = bundle.getString(ID_TOKEN);
// now.ggのサーバーURLを取得し、ユーザーの詳細を取得し、トークンを検証します
final String hostUrl = bundle.getString(HOST_URL);
verifyToken(token, hostUrl);
}
else {
// トークンの取得に失敗しました
// エラーの場合。開発者はエラーを表示するか、他のログイン方法を表示できます
Log.d(TAG, "run: get token failed " + bundle);
}
} catch (AuthenticatorException | IOException | OperationCanceledException e) {
e.printStackTrace();
}
}
}
次に、OnTokenAcquired で受け取った id_token の整合性を verifyToken 関数を呼び出して検証し、以下のようにユーザーの詳細を取得する必要があります:
private void verifyToken(String idToken, String hostUrl) {
BackendApiCallService backendApiCallService = getBackendRetrofit(hostUrl).create(BackendApiCallService.class);
Call < TokenVerifyResponse > tokenVerifyResponseCall = backendApiCallService.verifyIdToken(new TokenVerifyRequest(ID_TOKEN, idToken, CLIENT_ID));
tokenVerifyResponseCall.enqueue(new Callback < TokenVerifyResponse > () {
@Override
public void onResponse(Call < TokenVerifyResponse > call, Response < TokenVerifyResponse > response) {
if (response.isSuccessful()) {
Log.d(TAG, "onResponse: " + response.body().toString());
} else {
Gson gson = new Gson();
TokenVerifyResponse error = gson.fromJson(response.errorBody().charStream(), TokenVerifyResponse.class);
if (!error.isSuccess() && ("EXPIRED_TOKEN".equals(error.getCode()) || "INVALID_TOKEN".equals(error.getCode()))) {
// retry the verify token call, after getting a new TOKEN
}
}
}
@Override
public void onFailure(Call call, Throwable t) {
Log.d(TAG, "onFailure() called with: call = [" + call + "], t = [" + t + "]");
}
});
}
public Retrofit getBackendRetrofit(String hostUrl) {
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
return new Retrofit.Builder()
.baseUrl(hostUrl)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
}
public interface BackendApiCallService {
@POST("/accounts/oauth2/v1/verify-token")
Call < TokenVerifyResponse > verifyIdToken(@Body TokenVerifyRequest authRequest);
}
public class TokenVerifyRequest {
String token_type;
String token;
String client_id;
public TokenVerifyRequest(String token_type, String token, String client_id) {
this.token_type = token_type;
this.token = token;
this.client_id = client_id;
}
}
public class TokenVerifyResponse {
boolean success;
String code;
String msg;
@SerializedName("decodedData")
UserDataVerified userDataVerified;
public TokenVerifyResponse(boolean success, String code, String msg, UserDataVerified userDataVerified) {
this.success = success;
this.code = code;
this.msg = msg;
this.userDataVerified = userDataVerified;
}
public UserDataVerified getUserDataVerified() {
return userDataVerified;
}
public boolean isSuccess() {
return success;
}
public String getCode() {
return code;
}
@Override
public String toString() {
return "TokenVerifyResponse{" +
"success=" + success +
", code='" + code + '\'' +
", msg='" + msg + '\'' +
", userDataVerified=" + userDataVerified +
'}';
}
}
UserDataVerifiedクラスの詳細については、プロファイル情報の取得セクションを参照してください。
注意:
EXPIRED_TOKENやINVALID_TOKENなどのレスポンスが返ってきた場合は、signIn関数を再度呼び出すことで新しいトークンを要求することができます。このセクションでは、ユーザーのログアウトを実装する方法を説明します。
ユーザーのログアウトを実行するには:
以下のセクションでは、取得したユーザープロフィール情報の使用プロセスを説明します。
id_tokenを取得します。OnTokenAcquiredで受け取ったユーザー情報を取得するには、verifyToken関数を呼び出す必要があります。アプリにバックエンドサーバーがない場合は、以下のセクションを使用してユーザープロファイル情報を取得できます。
デバイス上のAPI呼び出しを使用して、ログインしているユーザーのプロファイル情報を取得できます。これを行うには、verifyToken関数を呼び出して受信したTokenVerifyResponseの userDataVerifiedフィールドを使用します。
UserDataVerified userData = tokenVerifyResponse.getUserDataVerified();
String userId = userData.getUserId();
String name = userData.getName();
String email = userData.getEmail();
String picture = userData.getPicture();
public class UserDataVerified {
String iss;
String sub;
String aud;
String exp;
String iat;
String auth_time;
String tokenId;
String sessionId;
String scope;
String email;
String name;
String picture;
String mobile;
String userId;
public UserDataVerified(String iss, String sub, String aud, String exp, String iat,
String auth_time, String email, String mobile, String userId,
String tokenId, String sessionId, String scope, String name, String picture) {
this.iss = iss;
this.sub = sub;
this.aud = aud;
this.exp = exp;
this.iat = iat;
this.auth_time = auth_time;
this.email = email;
this.mobile = mobile;
this.userId = userId;
this.tokenId = tokenId;
this.sessionId = sessionId;
this.scope = scope;
this.name = name;
this.picture = picture;
}
@Override
public String toString() {
return "UserDataVerified{" +
"iss='" + iss + '\'' +
", sub='" + sub + '\'' +
", aud='" + aud + '\'' +
", exp='" + exp + '\'' +
", iat='" + iat + '\'' +
", auth_time='" + auth_time + '\'' +
", tokenId='" + tokenId + '\'' +
", sessionId='" + sessionId + '\'' +
", scope='" + scope + '\'' +
", email='" + email + '\'' +
", name='" + name + '\'' +
", picture='" + picture + '\'' +
", mobile='" + mobile + '\'' +
", userId='" + userId + '\'' +
'}';
}
}
userData.getUserId()を使用してuserIdを取得できます。userIdを取得できます。ユーザーアカウントサービス
ユーザーアカウントサービス
ドキュメント改訂版 1.0