Android
Initial Setup
The LoginID Android SDK enables you to add passkey authentication in your native Android application without having to redirect the user to any pages outside your application.
The SDK leverages the Credential Manager API for creating and syncing passkeys with Google Password Manager.
Required settings:
- Host Digital Asset Links JSON file
- Base URL
The LoginID Android Mobile SDK requires Android 9+ (API 28+) for compatibility.
Configure assetlinks.json File
To make your app work with the SDK, you need to link your app to your website. This is done by using a file called Digital Asset Links. You must create this file and then place it on your website.
Find package name
If you need to find the package name of your Android app you can find it in your app's build.gradle
file under the defaultConfig
section.
Generate SHA-256 Fingerprint of Your App's Signing Key
The SHA256 fingerprint is a unique hash value generated from the app's certificate, which is used to identify the app's authenticity and integrity.
You can find your app's SHA256 fingerprint by using the keytool utility that comes with the Java Development Kit (JDK). And run the following command while replacing KEYSTORE_PATH
with the path to your keystore file, KEYSTORE_ALIAS
with your key alias, KEYSTORE_PASSWORD
and KEY_PASSWORD
are replaced with the actual passwords for your keystore and key.
keytool -list -v -keystore KEYSTORE_PATH \
-alias KEYSTORE_ALIAS \
-storepass KEYSTORE_PASSWORD \
-keypass KEY_PASSWORD
This command will output various certificate information, including the SHA256 fingerprint.
The keytool command can be found at $JAVA_HOME/bin if it isn't globally available.
When you're developing an app locally, it's simpler to use your default debug keystore for testing purposes. Find where your debug keystore is located and run the command on that.
Replace the arguments with the default values for the debug keystore.
- KEYSTORE_ALIAS: androiddebugkey
- KEYSTORE_PASSWORD: android
- KEY_PASSWORD: android
In a production environment, you should opt for a dedicated keystore. If you need to find your SHA256 fingerprint, especially for Google Play Console related tasks, you can do so directly within the Google Play Console.
Host assetlinks.json
file on Your Website Directory
Host the file under the correct path <WEBSITE_DOMAIN>/.well-known/assetlinks.json
in the root directory of your website.
Here is an example of the minimum required fields in the file:
[
{
relation: [
"delegate_permission/common.handle_all_urls",
"delegate_permission/common.get_login_creds",
],
target: {
namespace: "android_app",
package_name: "<PACKAGE_NAME>",
sha256_cert_fingerprints: ["<SHA256_FINGERPRINT>"],
},
},
];
Use the following example as a template and replace PACKAGE_NAME
and SHA256_FINGERPRINT
with your values.
Declare Association in the Android App
To associate your Android app, update your strings.xml
file with the website's URL.
<resources>
<string name="asset_statements" translatable="false">
[{
\"include\": \"<WEBSITE_DOMAIN>/.well-known/assetlinks.json\"
}]
</string>
</resources>
Then modify the AndroidManifest.xml
to include a meta-data element referencing this URL.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
<application
...
<meta-data android:name="asset_statements" android:resource="@string/asset_statements" />
...
</application>
</manifest>
Create Application
Create a new application to obtain your base URL
.
Add Android Fingerprint to Application
Enter the SHA256 created previously found under the Fido2
section of your application.
Add SDK to Existing Application
Adding the SDK to your application currently requires a download and manual import via an .aar
(Android ARchive).
Download the SDK
After creating an application, visit the Android section in the Get Started
guide to download the latest SDK. The SDK is provided as an .aar
file, which will be imported into your application.
Import the Android ARchive
To incorporate the SDK into your project, add the .aar
file and its dependencies to your app's build.gradle file.
dependencies {
// Path to the SDK's Android Archive
implementation files('./libs/api-release.aar')
// External dependencies required by the SDK
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'androidx.credentials:credentials:1.2.0'
implementation 'androidx.credentials:credentials-play-services-auth:1.2.0'
}
Create an SDK Instance
- Java
- Kotlin
public class MyApplication extends AppCompatActivity {
private LoginIDServiceConfig config = new LoginIDServiceConfig("<BASE_URL>");
LoginID.Companion.configure(config);
protected void onCreate() {
super.onCreate();
// any other configurations
// ...
// ...
}
}
class MyApplication : Application() {
private val config = LoginIDServiceConfig("<BASE_URL>")
LoginID.configure(config)
override fun onCreate() {
super.onCreate()
// any other configurations
// ...
// ...
}
}
API Reference
Java does not natively support Kotlin's coroutine features like suspending functions, requiring explicit callback mechanisms for interoperability. The Bidirectional
API facilitates this by serving as a callback system, allowing Java to handle continuations and manage asynchronous operations initiated by Kotlin's suspending functions. This enables seamless integration of asynchronous behaviors between Java and Kotlin in a mixed-codebase environment.
registerWithPasskey
Allows a user to sign up or add a new passkey using their username.
If options.usernameType
is set to email
(the default setting), the user will have a verified email profile.
Requires one of the following to add a new passkey to an existing user:
- User must be signed in.
- Usage of authorization tokens.
suspend fun registerWithPasskey(
activity: Activity,
username: String,
options: LoginIDOptions?
)
Parameter | Type | Required | Details |
---|---|---|---|
activity | Activity | true | The context used to launch any UI needed; use an activity context to make sure the UI will be launched within the same task stack. |
username | String | true | Username of the customer to be registered. |
options | LoginIDOptions | false | Additional options for the sign-up process. |
options.displayName | String | false | A human-palatable name for the user account, intended only for display on your passkeys and modals. |
options.usernameType | String | false | Specify username type validation. Types include email or phone . |
options.token | string | false | The user's authentication token, which may also be a management token with the scope passkey:write . |
authenticateWithPasskey
Sign in a previously registered user with a passkey.
suspend fun authenticateWithPasskey(
activity: Activity,
username: String,
options: LoginIDOptions?
)
Parameter | Type | Required | Details |
---|---|---|---|
activity | Activity | true | The context used to launch any UI needed; use an activity context to make sure the UI will be launched within the same task stack. |
username | String | true | Username of the customer to sign-in with. Passing an empty string will trigger usernameless authentication , where the user can select their passkey profile to sign-in with. |
options | LoginIDOptions | false | Additional options for the sign-in process. |
options.usernameType | String | false | Specify username type validation. Types include email or phone . |
generateCodeWithPasskey
Generates a code by authenticating with a passkey for the specified username and purpose. The response will include an OTP that can be used for other forms of authentication and recovery flows.
Have a look at the recovery flow guide on how to implement this feature.
suspend fun generateCodeWithPasskey(
activity: Activity,
username: String,
options: LoginIDOptions? = null
)
Parameter | Type | Required | Details |
---|---|---|---|
activity | Activity | true | The context used to launch any UI needed; use an activity context to make sure the UI will be launched within the same task stack. |
username | String | true | Username of the customer to sign-in with. Passing an empty string will trigger usernameless authentication , where the user can select their passkey profile to sign-in with. |
options | LoginIDOptions | false | Additional options for the code generation process. |
options.usernameType | String | false | Specify username type validation. Types include email or phone . |
sendCode
Sends an authentication code to the specified user via the chosen method. The username must have either an email
or phone
profile for the method to work.
Use the authenticateWithCode method to verify the code sent to the user.
suspend fun sendCode(
username: String,
method: MessageType = MessageType.EMAIL,
options: LoginIDOptions? = null
)
Parameter | Type | Required | Details |
---|---|---|---|
username | String | true | Username of the customer to send the code to. |
method | MessageType | false | Method to send the code, either EMAIL or SMS . Defaults to EMAIL . |
options | LoginIDOptions | false | Additional options for sending the code. |
options.usernameType | String | false | Specify username type validation. Types include email or phone . |
authenticateWithCode
Authenticate with one-time authentication for the given username.
Have a look at the recovery flow guide on how to implement this feature.
For further implementation details have a look at the cross device authentication guide.
suspend fun authenticateWithCode(
username: String,
code: String,
options: LoginIDOptions? = null
)
Parameter | Type | Required | Details |
---|---|---|---|
username | String | true | Username of the customer to authenticate. |
code | String | true | The code to authenticate. |
options | LoginIDOptions | false | Additional options for the authentication process. |
options.usernameType | String | false | Specify username type validation. Types include email or phone . |
confirmTransaction
Enables secure transaction confirmation using a passkey, incorporating transaction validation for actions such as payments or modifications to sensitive account information. This method ensures that the transaction is authorized by the rightful passkey owner. In all, it is similar to authenticateWithPasskey with extra data related to the transaction.
Have a look at the transaction confirmation guide on how to use this.
suspend fun confirmTransaction(
activity: Activity,
username: String,
payload: String,
options: LoginIDOptions?
)
Parameter | Type | Required | Details |
---|---|---|---|
activity | Activity | true | The context used to launch any UI needed; use an activity context to make sure the UI will be launched within the same task stack. |
username | String | true | The username for the account attempting to perform transaction confirmation. |
options | LoginIDOptions | false | Additional options for the transaction confirmation process. |
options.nonce | String | false | A unique nonce to ensure the transaction's integrity and prevent replay attacks |
options.txType | String | false | Specify the type of transaction being confirmed for additional validation. |
listPasskeys
Retrieve a list of the users' passkeys from the server.
Requires one of the following:
- User must be signed in.
- Usage of authorization tokens.
suspend fun listPasskeys(
options: LoginIDOptions?
)
Parameter | Type | Required | Details |
---|---|---|---|
options | LoginIDOptions? | false | Additional options for the list passkeys process. |
options.token | string | false | The user's authentication token, which may also be a management token with the scope passkey:read . |
renamePasskey
Renames a passkey user credential.
Requires one of the following:
- User must be signed in.
- Usage of authorization tokens.
suspend fun renamePasskey(
id: String
name: String
options: LoginIDOptions?
)
Parameter | Type | Required | Details |
---|---|---|---|
id | String | true | The UUID of the passkey attempting to rename. |
name | String | true | The new name for the passkey. |
options | LoginIDOptions? | false | Additional options for the renaming passkey process. |
options.token | string | false | The user's authentication token, which may also be a management token with the scope passkey:write . |
deletePasskey
Deletes a passkey user credential.
Requires one of the following:
- User must be signed in.
- Usage of authorization tokens.
suspend fun deletePasskey(
id: String
options: LoginIDOptions?
)
Parameter | Type | Required | Details |
---|---|---|---|
id | String | true | The UUID of the passkey attempting to delete. |
options | LoginIDOptions? | false | Additional options for the delete passkey process. |
options.token | string | false | The user's authentication token, which may also be a management token with the scope passkey:write . |
isLoggedIn
Check if a given user is currently logged in.
None.
public fun isLoggedIn(): Boolean
getUser
Retrieves the authenticated user data.
public fun getUser(): User
signout
Signs out the authenticated user, if the user is set.
None.
public fun signout(): Unit
The Android SDK does not automatically remember if a user is logged in once the app is closed. Functions like isLoggedIn, getUser, and signout work only while the app remains open. Developers, for now, will need to manually manage user sessions to maintain login status across app restarts.
Errors
LoginIDError
Can occur during the authentication process. It is designed to encapsulate detailed information about login-related errors, making it easier to handle and debug issues related to user authentication.
Field | Type | Details |
---|---|---|
msgCode | string | The error code associated with the login error. Defaults to unknown_error . |
msg | string | The detailed message or description of the error. Defaults to unknown error . |
messgage | string | The detailed message or description of the error. Defaults to unknown error . |