You may want your app, which runs on an Android device and is distributed through AppTouch, to support HUAWEI ID sign-in via authorization code through the OAuth 2.0 protocol and obtain the domain name of the Account Kit server from the AppTouch Global Router Service (GRS) server based on the carrier ID.
Then, your app will obtain the user's authorization code (temporary authorization credential) for identity verification, enabling secure sign-in. When a user signs in for the first time, your app will request authorization from the user. After the user's identity verification information expires, your app server will use the refresh token to request a new access token from the Account Kit server. No more authorization is required, so this method is more reliable and convenient. However, this mode is applicable only to apps that have their own servers.
The complete process for sign-in on an app released on AppTouch using the authorization code mode is as follows:
We provide some icon resources, which you can obtain by referring to (Optional) Obtaining Icon Resources.
Java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// activity_main is the name of the custom layout file.
setContentView(R.layout.activity_main);
findViewById(R.id.HuaweiIdAuthButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
silentSignInByHwId();
}
});
}
Java
// AccountAuthService provides a set of APIs, including silentSignIn, getSignInIntent, and signOut.
private AccountAuthService mAuthService;
// Specify the user information to be obtained after user authorization.
private AccountAuthParams mAuthParam;
// Define the request code for signInIntent.
private static final int REQUEST_CODE_SIGN_IN = 1000;
// Define the log tag.
private static final String TAG = "Account";
/**
* Silent sign-in: If a user has authorized your app and signed in, no authorization or sign-in screen will appear during subsequent sign-ins, and the user will directly sign in.
* After a successful silent sign-in, the HUAWEI ID information will be returned in the success event listener.
* If the user has not authorized your app or signed in, the silent sign-in will fail. In this case, your app will show the authorization or sign-in screen to the user.
*/
private void silentSignInByHwId() {
// 1. Use AccountAuthParams to specify the user information to be obtained after user authorization, including the user ID (OpenID and UnionID), email address, and profile (nickname and profile picture).
// 2. By default, DEFAULT_AUTH_REQUEST_PARAM specifies two items to be obtained, that is, the user ID and profile.
// 3. If your app needs to obtain the user's email address, call setEmail().
// 4. To support authorization code-based HUAWEI ID sign-in, use setAuthorizationCode(). All user information that your app is authorized to access can be obtained through the relevant API provided by the Account Kit server.
// 5. Use setCarrierId() to build the request for obtaining the carrier ID. It will be returned when you call the silentSignIn or getSignInIntent API.
mAuthParam = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setEmail()
.setAuthorizationCode()
.setCarrierId()
.createParams();
// Use AccountAuthParams to build AccountAuthService.
mAuthService = AccountAuthManager.getService(this, mAuthParam);
// Sign in with a HUAWEI ID silently.
Task<AuthAccount> task = mAuthService.silentSignIn();
task.addOnSuccessListener(new OnSuccessListener<AuthAccount>() {
@Override
public void onSuccess(AuthAccount authAccount) {
// The silent sign-in is successful. Process the returned AuthAccount object to obtain the HUAWEI ID information.
dealWithResultOfSignIn(authAccount);
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// The silent sign-in fails. Your app will call getSignInIntent() to show the authorization or sign-in screen.
if (e instanceof ApiException) {
ApiException apiException = (ApiException) e;
Intent signInIntent = mAuthService.getSignInIntent();
startActivityForResult(signInIntent, REQUEST_CODE_SIGN_IN);
}
}
});
}
/**
* Process the returned AuthAccount object to obtain the HUAWEI ID information.
*
* @param authAccount AuthAccount object, which contains the HUAWEI ID information.
*/
private void dealWithResultOfSignIn(AuthAccount authAccount) {
Log.i(TAG,"code:"+authAccount.getAuthorizationCode());
Log.i(TAG,"code:"+authAccount.getCarrierId());
// TODO: After obtaining the authorization code and carrier ID, your app needs to send them to the app server.
}
Java
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_SIGN_IN) {
Log.i(TAG, "onActivitResult of sigInInIntent, request code: " + REQUEST_CODE_SIGN_IN);
Task<AuthAccount> authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
if (authAccountTask.isSuccessful()) {
// The sign-in is successful, and the authAccount object that contains the HUAWEI ID information is obtained.
AuthAccount authAccount = authAccountTask.getResult();
dealWithResultOfSignIn(authAccount);
Log.i(TAG, "onActivitResult of sigInInIntent, request code: " + REQUEST_CODE_SIGN_IN);
} else {
// The sign-in fails. Find the failure cause from the status code. For more information, please refer to the "Error Codes" section in the API Reference.
Log.e(TAG, "sign in failed : " +((ApiException)authAccountTask.getException()).getStatusCode());
}
}
} Implement this by yourself.
Enable your app server to obtain the domain name of the Account Kit server by following the instructions in Obtaining the Kit Server URL. Pass the carrier ID obtained in 1 and specify the service name as described in the following table. Then, the AppTouch GRS server will return the domain name of the Account Kit server based on the service name in the request body. The domain name is in key-value format.
Service Name |
Domain Name Key |
Domain Name Value |
|---|---|---|
oauth.apptouch |
token |
Domain name for Obtaining an Access Token. |
tokeninfo |
Domain name for Parsing an Access Token. |
|
account.apptouch |
userinfo |
Domain name for Obtaining User Information. |
After obtaining the authorization code, your app uses it to obtain the access token and refresh token from the Account Kit server through the API for Obtaining an Access Token provided by this server. If any error occurs during the API call, please refer to Error Codes.
An authorization code can be used only once and is valid only for 5 minutes. If the error indicating that an authorization code has expired or has been used occurs, your app needs to obtain a new authorization code.
Call the API for Obtaining User Information provided by the Account Kit server to obtain user information, including the user nickname, profile picture, and email address.
Processing after an access token has expired:
An access token has a short validity period (60 minutes). When an access token has expired or is about to expire (NSP_STATUS error code returned, if you use such a token), request a new access token from the Account Kit server by sending the refresh token (validity period: 180 days) through the API for Obtaining an Access Token.
Processing after a refresh token has expired:
The validity period of a refresh token is 180 days. When a refresh token has expired (error code returned, if you use such a token), the app server needs to notify your app to call the sign-in API of the Account SDK again and request the user to re-authorize.
You can choose whether to implement this function as needed. If needed, follow the instructions in (Optional) Independent Authorization.
When a user requests to sign out, your app will call the signOut API to sign the user out and notify the Account SDK of the sign-out. Then the Account SDK will delete the relevant HUAWEI ID information.
Java
@Override
protected void onCreate(Bundle savedInstanceState) {
findViewById(R.id.HuaweiIdSignOutButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signOut();
}
});
}
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
findViewById<View>(R.id.HuaweiIdSignOutButton).setOnClickListener { signOut() }
}
Java
private void signOut() {
Task<Void> signOutTask = mAuthService.signOut();
signOutTask.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.i(TAG, "signOut Success");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.i(TAG, "signOut fail");
}
});
}
Kotlin
private fun signOut() {
val signOutTask = mAuthService!!.signOut()
signOutTask.addOnSuccessListener {
Log.i(TAG, "signOut Success")
}.addOnFailureListener {
Log.i(TAG, "signOut fail")
}
}
To improve privacy security, your app should allow users to cancel authorization.
After a user request to cancel authorization from your app, the cancelAuthorization method of the AccountAuthService class is called to complete the cancellation.
Java
@Override
protected void onCreate(Bundle savedInstanceState) {
findViewById(R.id.HuaweiIdCancelAuthButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cancelAuthorization();
}
});
}
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
findViewById<View>(R.id.HuaweiIdCancelAuthButton).setOnClickListener { cancelAuthorization() }
}
Java
private void cancelAuthorization() {
Task<Void> task = mAuthService.cancelAuthorization();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.i(TAG, "cancelAuthorization success");
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.i(TAG, "cancelAuthorization failure:" + e.getClass().getSimpleName());
}
});
}
Kotlin
private fun cancelAuthorization() {
val task = mAuthService!!.cancelAuthorization()
task.addOnSuccessListener {
Log.i(TAG, "cancelAuthorization success")
}
task.addOnFailureListener { e ->
Log.i(TAG, "cancelAuthorization failure:" + e.javaClass.simpleName)
}
}
If your app requires a user to enter a mobile number and verifies the user identity using an SMS verification code, you can integrate the ReadSmsManager service so that your app can automatically read the SMS verification code without obtaining the SMS reading permission. After the integration, SMS verification codes are automatically filled in for the verification, greatly improving user experience. To learn more, please refer to (Optional) Automatically Reading an SMS Verification Code Without User Authorization.
If your app requires a user to enter a mobile number and verifies the user identity using an SMS verification code, you can integrate the ReadSmsManager service so that your app can first get user authorization, and then automatically read the SMS verification code without obtaining the SMS reading permission. After the integration, SMS verification codes are automatically filled in for the verification, greatly improving user experience. To learn more, please refer to (Optional) Automatically Reading an SMS Verification Code After User Authorization.