Authentication Options
The SDK supports the following authentication options:
Recommended Option:
- 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
- Password authentication requires the following keys/values in
Senibill.plist
API_KEY
API_SECRET
CREDENTIAL_TYPE
REDIRECT_URL
- 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
- Instantiate and retain an instance of
PasswordAuthenticator
. - 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 theiraccessId
as described inLogin 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.
Property | Description |
---|---|
clientKey | This is the Client Key, provided by Sensibill. It is a very long, random string encoded in base64. |
clientSecret | This is the Client Secret, provided by Sensibill. |
credentialType | This represents the type of credential being used to authenticate the user, provided by Sensibill. |
redirectUri | URL provided by Sensibill for the client. Used for OAuth 2.0. |
isRedirect | Can be either true or false . Tells whether or not the authorizationGrant endpoint will issue a redirect if it successfully authenticates the user. |
sensibillEnv | An 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