This tutorial explains a sample implementation of offline user authentication.
The goal of offline authentication is to make the login/logout end-user experience consistent whether online or offline.
It is assumed that the developer is familiar with IBM MobileFirst Platform Foundation application development, adapter-based authentication and JSONStore.
The associated sample project demonstrates an end-to-end scenario. However, there are many ways to achieve the same results.
Topics covered, are:
Offline authentication concept
By using offline authentication, an end-user is able to authenticate even if an Internet connection is unavailable.
An Online login is necessary when logging-in is attempted for the first time, so that the MobileFirst Server validates the user’s credentials. After successful validation, a JSONStore is created for the logged-in user. The Offline authentication is implemented by opening the mentioned JSONStore for the supplied username and password. This is further explained below.
The sample application for this tutorial has the following structure:
- An unsecured area, which is accessible without authentication
- A secured area, which is accessible only after authentication, whether online or offline
- The same login form for both online and offline authentication, so that the end-user experience is the same whether online and offline
- Support for logging-out
Going through the online and offline flows from a high-level point of view:
Before either online or offline authentication occurs, an Internet connection is checked for first. Depending on the result, the appropriate authentication flow is used.
Steps 2 and 3:
The online authentication flow is implemented as explained in the adapter-based authentication in hybrid applications tutorial.
Steps 4 and 5:
After a successful login, a JSONStore is created using the end-user’s username and encrypted using the user's password.
The secured area is displayed.
Steps 2 and 3:
The authentication process tries to open the previously created JSONStore by using the end-user’s password that was passed as input.
If the attempt is successful, the secured area is displayed.
Implementing the authentication flows
Keep in mind that some of the implementation code relates to the application UI.
offlineLoggedIn global variables help determine the user’s login state, whether connected or not connected to the Internet.
Prerequisite: When an end-user tries to log in for the very first time, Internet connection must be available so that the user credentials can be verified against the server backend.
Therefore, before any authentication is performed, Internet connection is checked so that the appropriate authentication flow is executed.
- The online authentication flow uses the same code as provided in the single-step adapter authentication sample application.
- In order to simulate a back-end of multiple users, a valid login is considered one where the
username == password, no matter what the username is.
submitAuthenticationfunction in the adapter's
*-impl.jsfile is therefore modified to:
Because the authentication simulates multiple users, usage of multiple JSONStores is required as well, in order to accommodate for the many users.
WL.JSONStore.init, the username is passed as a parameter for a new JSONStore to be opened for each authenticated user. For this, declare a collection to define the structure of the JSONStore:
Below is the complete implementation, followed by a breakdown and explanation code block by code block.
The sample application contains additional comments.
Check whether the user is already authenticated
true, display the secured area.
false, display the login form and start authentication via the challenge handler.
If the connection to the Internet is established and the user is authenticated on the back end but the username variable is empty, assume that a logout happened offline.
Log out the user from the realm before trying to log in again online.
If logging-in while offline and Internet connection is then available, log in to the realm without showing the login form.
If online authentication fails, for example if MobileFirst Server is unavailable, offline authentication is attempted instead.
Upon successful online authentication, the secured area can be displayed.
The username and password are saved for future use.
A JSONStore for the user is initialized from the user’s username and encrypted by using the user’s password.
Before populating the collection, it is best to check whether it is already populated from a previous login attempt. Return the contents of the collection.
If the collection is empty, populate it.
If the collection is not empty, do not populate it again.
Finally, the username and password variables are emptied, the JSONStore is closed and the secured area is displayed.
In the offline authentication flow, a couple of additional scenarios require dealing with:
- Empty username and password fields
- First-time log-in when offline
- Already authenticated users
In online authentication, if
username != password, the authentication process stops. In contrast, during offline authentication in JSONStore, the following cases must be addressed:
- Empty username and password fields destroy your JSONStore. As a result, users can no longer log in offline until the next online authentication, where the JSONStore is created again if it does not exist.
- First-time log-in cannot happen because there is no JSONStore yet.
This function first checks whether the user is already authenticated.
If the user is not authenticated, offline authentication is attempted.
Check the validity of the user credentials.
If they are not valid, display an error message.
If they are valid, try to open and decrypt the user’s JSONStore by using the user’s password.
Then, Check the contents of the store.
If the store is empty, this user did not previously log in: no stored data in the collection.
Destroy the store for this username and provide an appropriate error message.
If the JSON store is NOT empty, set the offlineLoggedIn flag to true and display the secured area.
Upon logout, mark the user as logged out:
Empty the username and password variables.
Close the JSONStore.
Set the offlineLoggedIn flag to false.
Check the Internet connection before logging out.
If available, log out the user from the realm and display the unsecured area.
If online logout fails (for example because MobileFirst Server is not available), logging out will take place anyway. See online authentication in case the username variable is empty.
The end result
Note: The sample code that is written in this tutorial is only a suggestion. You can use other implementation methods.
To use the sample:
- Import the MobileFirst project into MobileFirst Studio.
- Deploy the adapter and application.
- Launch the application on a device.
- Start online and log in by using, for example, mobile/mobile as the username and password. The secured area is then displayed
- Log out.
- In the device settings, change to airplane mode and log in again. The secured area is then displayed, in “offline access”.
Click to download the Studio project.