Integrating now.gg Login

Follow the steps on this page to integrate now.gg Login into your Android app, configure it and add the now.gg Sign-in button to your app’s layout that starts the login flow.

Before you start

Make sure you have completed the prerequisites checklist and set up your developer environment.

Add Permissions and Assets

1. Add the permissions to AndroidManifest.xml
 <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
  <uses-permission android:name="android.permission.INTERNET"/> 
2. Add dependencies in your application build.gradle file
//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. Add the now.gg Sign-in Button
  1. Download the now.gg Sign-in button resource assets.
  2. Add the now.gg Sign-in button in your application’s layout:
    Button signInButton = findViewById(R.id.now_gg_login_button);
    
  3. In the Android activity (for example, in the onCreate method), register your button’s OnClickListener to sign in the user on click:
    findViewById(R.id.now_gg_login_button).setOnClickListener(this);

Note:

  • In case the user is already logged-in with a now.gg account in your app, you should save that information in your app’s database and use it to skip the login process when the user launches your app again.
  • In case you wish to implement automatic login in your app and skip the login button flow, you may do so by directly implementing the signIn() function as illustrated in the third step below (code for Sign-in with now.gg Account).

Start the Login Flow

1. Execute the Sign-in Button Tap

In the Android activity’s onClick method, execute the sign-in button tap by logging in the now.gg account.

@Override
 public void onClick(View v) {
    switch (v.getId()) {
        case R.id.now_gg_login_button:
             signIn();
             break;
          // ...
    }
 }
2. Add implements View.OnClickListener and check for GET_ACCOUNTS permission
To your main activity, add the implements View.OnClickListener and check for GET_ACCOUNTS permission:
private final int GET_ACCOUNTS_REQUEST_CODE = 100;
 public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 }
  • To check for GET_ACCOUNTS permission, add the following code to your onCreate method:
    @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");
         }
     }
    
  • To check for results, add the following code to your 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.
             }
         }
     }
    

Get User and Session Information

  • We also offer an advanced and more secure Auth Code Flow for now.gg Login integration.
  • This flow enables you to get detailed user and session information.
  • After you have completed the steps above, navigate to this section to implement now.gg Login using Auth Code flow.
  • If you only wish to fetch basic profile information after the user sign-in, you can continue with the steps below.

Continue with Basic Login Flow

3. Code for Sign-in with now.gg Account:
 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");
         startActivity(intent);
     } catch (ActivityNotFoundException e) {
         e.printStackTrace();
     }
  }
4. After the user signs in, you get the requested token (id_token) in OnTokenAcquired callback function

This token can be used to get the user’s details by verifying the token or passing the token to your backend server. You will get the user details from your server as a response.

      
 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);
            // get the now.gg server URL, from which you can get the user details and verify the tokens

            final String hostUrl = bundle.getString(HOST_URL);
            verifyToken(token, hostUrl);
            }
            else {
                 // get token failed
                 // error case. The developer can show errors or show other login mechanisms
                 Log.d(TAG, "run: get token failed " + bundle);
                 }
          } catch (AuthenticatorException | IOException | OperationCanceledException e) {
            e.printStackTrace();
          }
     }
 }
5. Validate the ID token for the user & get user details

Now, you have to verify the integrity of id_token (that you received in OnTokenAcquired), by calling the verifyToken function and get the user’s details.

     
  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 +
                '}';
    }
}

For more information on the UserDataVerified class, please refer to the Retrieve Profile Information section.

Note:

  • If you get responses such as EXPIRED_TOKEN or INVALID_TOKEN, you can request a new token by calling the signIn function again.
  • To pass the currently signed-in user to a backend server, you should send the ID token to your backend server and validate it. See – Authenticate with a backend server.
×
Text copied to clipboard
Questions? Please reach out to us at dev-support@now.gg