Authentication Options

The SDK supports the following authentication options:

  • Custom Token Provider Authentication
  • With this option, the logic of creating User Accounts and getting User Access Tokens for them is handled by an Integration Service, created by a client in their backend.
  • Integrator then develops a Custom Token Provider on integrated app side, and the SDK will then use a token provided by a Custom Token Provider as a Bearer token in its network requests to the Sensibill API.
  • SDK supports Bearer tokens created using Authorization Code Flow, as well as JWT Authentication Flow.

Other Option:

  • Password Authentication
    • The SDK will perform user and token management directly against Sensibill API, without the Integration Service.
    • A registered user will have to provide their username and password to authenticate.
    • Note: Password authentication is not supported in the web SDK.

Both options adhere to the OAuth 2.0 standard.

Custom Token Provider Authentication

For details on Custom Token Provider Authentication, please see the Quick Start Page .

Password Authentication

PasswordAuthenticator class provides the following authentication and user management operations by interacting with Sensibill’s API.

  • User Authentication Flow
    • Login User
    • Logout User
  • User Registration Flow
    • Check username availability.
    • Check password strength.
    • Register a user.
  • Registered User Management Flow
    • Reset password

Prerequisites

  1. Password authentication requires the following keys/values in Senibill.plist
  • API_KEY
  • API_SECRET
  • CREDENTIAL_TYPE
  • REDIRECT_URL
  1. A user must also be registered using PasswordAuthenticator‘s registration flow. (see PasswordAuthenticator documentation)

Note:

  • The login operation requires a network connection, and cannot run in offline mode.
  • Optimally, the logout operation should be performed while connected to the network: this allows to end user’s session on Sensibill API server side. If, however, the network connection is unavailable during logout, the user session will be cleared locally on device.

Login User

  1. Instantiate and retain an instance of PasswordAuthenticator.
  2. Invoke login(accessId:password:completion:) function to authenticate a user.

Note:

  • login will also start the SDK. See SDK Lifecycle for further information.
  • login is an asynchronous operation. The caller must wait for the login callback to return and succeed before attempting any further interaction with SDK.
import Sensibill

let authenticator = PasswordAuthenticator()

//...

authenticator.login(accessId: "accessId", password: "password") { error in

  // Check for an error. If an error is returned, interaction with SDK will not be possible
  guard case .none = error else {
    // Add custom error handling
    return
  }

  // Start interacting with the SDK
}

//...

Logout User

Invoke logout(completion:) using existing instance of PasswordAuthenticator in order to logout the currently authenticated user and to stop the sdk.

Note:

  • logout will also stop the SDK. See SDK Lifecycle for further information.
  • logout is an asynchronous operation. The caller must wait for logout’s callback to return before attempting the next login operation.
authenticator.logout() { error in

  // Check for an error (optional). If an error is returned, the SDK will still log out locally.
  guard case .none = error else {
    // Add custom error handling
    return
  }

}

Re-login User

If necessary, you can call the login operation again (with the same or different credentials) once a logout operation is complete. Login, however, will fail if you attempt to call it 2 or more times without calling logout.

Auto Login

To login using last authenticated user (assuming the refresh token is still valid), invoke PasswordAuthenticator's login(accessId:password:completion:) method using nil as password with last authenticated user’s accessId.

  • If SDK is unable to login user with cached information, then it is required to authenticate with their password along with their accessId as described in Login User section on this page.
Info

It is recommended that you are already familiar with the content of the Quick Start Page prior to implementing Password Authentication.

Summary

SensibillAuth manages username/password login. Once an instance of it is created, its methods can be called in order to traverse authentication states.
The SensibillAuth object is able to generate a TokenProvider that can provide access tokens for the currently signed in user, which allows it to connect with the rest of the Sensibill SDK lifecycle.

Reference SensibillAuth
TokenProvider

Additional Dependencies

To use these classes, the following additional dependencies are required (unless sensibill-sdk-all is already being included):

implementation "com.getsensibill:sensibill-auth:X.X.X"
implementation "com.getsensibill:sensibill-oauth-client:X.X.X"

Required Inputs

In order to perform OAuth authentication, some client information is required. This information will be provided by Sensibill.

A chart of the required inputs will be provided below. When variables are referenced in the code examples, they will refer to the values defined here.

PropertyDescription
clientKeyThis is the Client Key, provided by Sensibill. It is a very long, random string encoded in base64.
clientSecretThis is the Client Secret, provided by Sensibill.
credentialTypeThis represents the type of credential being used to authenticate the user, provided by Sensibill.
redirectUriURL provided by Sensibill for the client. Used for OAuth 2.0.
isRedirectCan be either true or false. Tells whether or not the authorizationGrant endpoint will issue a redirect if it successfully authenticates the user.
sensibillEnvAn enum conforming to the DefaultEnvironment type. This specifies what external Sensibill environment you wish your application to access. Example: DefaultEnvironment.RECEIPTS_SANDBOX

Creating OAuthSettings

Before creating the SensibillAuth object, first create an OAuthSettings object which will hold client information like the client key and secret.

Kotlin

val oAuthSettings = OAuthSettings(clientKey, clientSecret, credentialType, redirectUri, isRedirect)

Java

OAuthSettings oAuthSettings = new OAuthSettings(clientKey, clientSecret, credentialType, redirectUri, isRedirect);

Reference
OAuthSettings


Creating SensibillAuth

Now, we must create a SensibillAuth object. This object will be used to perform the OAuth flow.

Create the SensibillAuth object by using SensibillAuthBuilder.

Kotlin

val auth: SensibillAuth = SensibillAuthBuilder(applicationContext, sensibillEnv, oAuthSettings)
    .build()

Java

SensibillAuth auth = new SensibillAuthBuilder(applicationContext, sensibillEnv, oAuthSettings)
        .build();

Reference SensibillAuthBuilder


Attaching SensibillAuth to the SensibillSDK

Now that we have a SensibillAuth object, we can use the TokenProvider it generates for SensibillSDK initialization.

Kotlin

val sensibillAuth: SensibillAuth // From above

val initializationBuilder = InitializationBuilder(applicationContext, sensibillEnv)
    .authTokenProvider(sensibillAuth.tokenProvider)

// ... Continue with initialization flow

Java

SensibillAuth sensibillAuth; // From above

InitializationBuilder initializationBuilder = new InitializationBuilder(applicationContext, sensibillEnv)
        .authTokenProvider(sensibillAuth.getTokenProvider());

// ... Continue with initialization flow

Reference Quick Start > Initializing the SDK
SensibillAuth
InitializationBuilder


Special Considerations

A user session must exist before starting the SDK

Though the TokenProvider will not be used when initializing the SDK, when starting the SDK the TokenProvider (in this case, our SensibillAuth) must be active and able to provide valid tokens for an active user session.
For a visualization of this restriction, please see the Android Lifecycle .

Due to this limitation, there are two recommended ways to navigate the SensibillSDK lifecycle when using Password Authentication:

Separating initialize and start:

Using this method, you could create your SensibillAuth object and initialize the SDK on your Sensibill SDK “Login” page, and only start the SDK after the user has successfully authenticated and is about to be directed to the next page.

Authenticating the user before calling initialize:

Using this method, you could create your SensibillAuth object on your Sensibill SDK “Login” page.
Then, only after the user has successfully authenticated, you can proceed to initialize and start the SDK, providing SensibillAuth’s TokenProvider while initializing.


Authenticating the User

As an example of how to use the SensibillAuth object for authentication, it can be given the user’s username and password to sign them in

Kotlin

val username = "username" // Taken from Username EditText
val password = "password" // Taken from Password EditText

auth.signIn(username, password, object : SensibillAuth.SessionListener {
    override fun onSuccess(session: OauthSession) {
        // The user is now signed in.
    }

    override fun onFailure(error: SensibillAuth.AuthError) {
        // Sign in failed, username or password incorrect
    }
})

Java

final String username = "username"; // Taken from Username EditText
final String password = "password"; // Taken from Password EditText

auth.signIn(username, password, new SensibillAuth.SessionListener() {
    @Override
    public void onSuccess(@NotNull OauthSession session) {
        // The user is now signed in.
    }

    @Override
    public void onFailure(@NotNull SensibillAuth.AuthError error) {
        // Sign in failed, username or password incorrect
    }
});

Reference SensibillAuth


Some other examples of SensibillAuth methods that will be commonly used for authentication flows are:

  • SensibillAuth.logout()
  • SensibillAuth.registerWithPassword()

For more details on SensibillAuth’s capabilities, please see the Reference Documentation