ネイティブAndroid用ログインモジュール

このページの手順に従って、now.ggログインをAndroidアプリに統合、設定し、ログインフローを開始するnow.ggサインインボタンをアプリのレイアウトに追加してください。

開始する前に

必須要項のチェックリストと開発環境のセットアップが完了していることを確認してください。

権限、依存関係、アセットを追加

1. 権限を追加する

まず、AndroidManifest.xmlに権限を追加します。

 <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
  <uses-permission android:name="android.permission.INTERNET"/> 

2. 依存関係の追加

次の依存関係をアプリケーションの 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'

3. now.ggサインインボタンの表示

3.1 now.ggサインインボタンのアセットをダウンロード

now.ggサインインボタンのアセットは、now.gg SDKパッケージAssets/Loginディレクトリに含まれています。

3.2 サインインボタンのオプションを選択
  • 推奨サインインボタン: 標準的なルック&フィール用に用意されたボタンアセットを使用してください。
  • カスタムサインインボタン: 用意されたロゴのみのアセットと独自のテキストを使用して、アプリのスタイルに合ったボタンをデザインして、カスタムの”now.ggでサインイン”ボタンを作成してください。
3.3 アプリケーションのレイアウトに ‘now.ggサインインボタン’ を追加:
Button signInButton = findViewById(R.id.now_gg_login_button);


ログインフローの開始

1. サインインボタンにOnClickイベントを追加

Android アクティビティの onCreate メソッドに、サインイン ボタンの OnClickListener を追加します。

 findViewById(R.id.now_gg_login_button).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
          signIn();
      }
  });

2. 権限と結果の確認

次に、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ログイン統合のための高度でより安全な認証コードフローも提供しています。
    • このフローでは、詳細なユーザー情報とセッション情報を取得することができます。
    • 上記の手順を完了したら、このセクションに移動し、Authコードフローを使用してnow.ggログインを実装します。
  • ユーザーがサインインした後に基本的なプロフィール情報のみを取得したい場合は、以下の手順に進んでください。

基本的なログインフローを続行する


3. サインインを実行する

次のコードサンプルは「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 & gt; 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");
         }
     }
 };

4. リクエストされたトークンを取得する

ユーザーがサインインした後、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();
          }
     }
 }

5. トークンを検証してユーザーの詳細を取得する

次に、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_TOKENINVALID_TOKENなどのレスポンスが返ってきた場合は、signIn関数を再度呼び出すことで新しいトークンを要求することができます。
  • 現在サインインしているユーザーをバックエンドサーバーに渡すには、IDトークンをバックエンドサーバーに送信し、それを検証する必要があります。バックエンドサーバとの認証を参照ください。
  • ユーザーがログインしたら、アプリのローカルデータベースまたは共有プレファレンスにログイン情報を保存して、次回以降の起動時に再度ログインの手続きを行わずに自動的にゲームを続けられるようにします。

6. ユーザーのログアウトを実装 -オプション

このセクションでは、ユーザーのログアウトを実装する方法を説明します。

ユーザーのログアウトを実行するには:

  • アプリのローカルデータベース/SharedPreferencesから保存されたログイン情報を削除し、ログイン画面を再表示します。
  • ログアウト後、ユーザーはゲストとして続けてプレイするか、ゲームで利用可能な他のログインオプションを使用することができます



プロファイル情報の使用

以下のセクションでは、取得したユーザープロフィール情報の使用プロセスを説明します。

now.ggアカウントでユーザーにサインインした後、id_tokenを取得します。OnTokenAcquiredで受け取ったユーザー情報を取得するには、verifyToken関数を呼び出す必要があります。
アプリにバックエンドサーバーがあり、サインインしたユーザーのユーザープロファイルをバックエンドで取得したい場合は、こちらのセクションを参照してください。

警告

    • 現在サインインしているユーザーをアプリのバックエンドサーバーに伝えるのに、ユーザーのメールアドレスやユーザーIDを使用しないでください。代わりに、ユーザーのIDトークンをバックエンドサーバーに送信し、サーバー上でトークンを検証してください。

アプリにバックエンドサーバーがない場合は、以下のセクションを使用してユーザープロファイル情報を取得できます。

プロファイル情報の取得

デバイス上のAPI呼び出しを使用して、ログインしているユーザーのプロファイル情報を取得できます。これを行うには、verifyToken関数を呼び出して受信したTokenVerifyResponseuserDataVerifiedフィールドを使用します。

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 + '\'' +
               '}';
   }
 }         
ユーザー情報を取得したら、その情報をアプリのデータベースに保存し、次回ユーザーがアプリを起動したときにログインプロセスをスキップするために使用する必要があります。

重要な情報

  • ユーザーを識別するためにメールアドレスを使用しないことをお勧めします。代わりにuserIdを使用してください。
  • アプリにバックエンドサーバーがない場合は、クライアントでuserData.getUserId()を使用してuserIdを取得できます。
  • アプリにバックエンドサーバーがある場合は、verify token APIを呼び出し、ユーザーデータと一緒にレスポンスとしてuserIdを取得できます。


×

ユーザーアカウントサービス

ネイティブAndroid用ログインモジュール

ユーザーアカウントサービス

ドキュメント改訂版 1.0

テキストがクリップボードにコピーされました。
copyLinkText
ご不明な点がございましたら、お気軽にお問い合わせください。 dev-support@now.gg