Appcelerator: Authentication in a mobile app

Mark OlsenSr. Developer
Published:
Preface: This article is part of a series focused on cross platform mobile app development (specifically Android and iOS) using the Alloy framework and Titanium Studio made by Appcelerator. This article presumes a working knowledge of Titanium Studio and the Alloy framework.

If you are creating a mobile app that requires authentication before performing any actions you may need to present the user with a login form. You also likely want to save the user's information so that after authenticating they don't need to see the login form the next time the app is started.

In the Alloy framework, the first window that is normally started is the "index.xml" window via the "$.index.open()" call in the "index.js" controller file. To handle opening either the login form ("LoginForm") or the home screen ("Home") of your app based on authentication you can do the following:

File: /app/controllers/index.js
var auth = require('auth');
                      
                      if (auth.isAuthenticated()) {
                         Alloy.createController("Home").getView().open();
                      } else {
                         Alloy.createController("LoginForm").getView().open();
                      }

Open in new window

The logic for "isAuthenticated()" will vary based on the individual app's requirements. In this example we are creating a library for authentication and calling the function within it. This 'auth' library will have a few functions declared as exports within that will be used in other controllers and will be outlined later in this article

The "LoginForm" view/controller will be responsible for accepting the user's input and validating the credentials. A simple form may look like this:

file: /app/views/LoginForm.xml
<Alloy>
                         <Window id="loginForm" layout="vertical">
                            <TextField id="loginName" hintText="Username"/>
                            <TextField id="password" hintText="Password" passwordMask="true"/>
                            <Button id="loginSubmit">Login!</Button>
                         </Window>
                      </Alloy>

Open in new window


The corresponding controller would accept the user's input and perform the validation function. If the user's credentials are correct, the "Home" page is opened:

file: /app/controllers/LoginForm.js
var args = arguments[0] || {};
                      
                      $.loginSubmit.addEventListener('click', function(e) {
                         var auth = require('auth');
                      
                         if (auth.validateCredentials($.loginName.value, $.password.value)) {
                            Alloy.createController("Home").getView().open();
                         } else {
                            alert("Invalid credentials!");
                         }
                      });

Open in new window


For this exercise, the "Home" screen of the app will just have a welcome message and a button to log out the user. Example view and controllers:

file: /app/views/Home.xml:
<Alloy>
                         <Window id="home" layout="vertical">
                            <Label>Welcome, you have been authenticated!</Label>
                            <Button id="logoutButton">Logout</Button>
                         </Window>
                      </Alloy>

Open in new window

file: /app/controllers/Home.js:

var args = arguments[0] || {};
                      
                      $.logoutButton.addEventListener('click', function(e) {
                         var auth = require('auth');
                         auth.logout();
                      });

Open in new window


For the app to remember is a user has previously authenticated (for the check in index.js) we can store some information using the Titanium.App.Properties interface. Warning: The properties are not encrypted, so storing plain text passwords is not recommended. Instead consider saving an encrypted authentication token. The 'auth' library will handle this and the functions used by the other controllers.

file: /app/lib/auth.js
// Authentication library
                      
                      // Custom logic to validate auth token may be required.
                      // In this example we are just checking to see if it exists.
                      exports.isAuthenticated = function() { 
                         var authToken = Ti.App.Properties.getString("authToken");
                         return (authToken != undefined);
                      };
                      
                      // Custom logic to validate the credentials will be required
                      // In this example we just test for a basic password
                      exports.validateCredentials = function(loginName, password) {
                         var isValid = (loginName == 'user1' && password == '1234');
                         
                         if (isValid) {
                            // Save the auth token
                            Ti.App.Properties.setString("authToken", "encryptedAuthTokenString");
                         }
                         
                         return isValid;
                      };
                      
                      // To logout the user, remove the property and return them to the LoginForm
                      exports.logout = function() {
                         Ti.App.Properties.removeProperty("authToken");
                         Alloy.createController("LoginForm").getView().open();   
                      };

Open in new window


By using these steps you will be able to do basic authentication and remembering a user for your app. All of the implementations are not device specific and will work for both iPhone and Android platforms.
 

Android gotcha: The Android platform has the very useful, but sometimes tricky, addition of the "Back" button that is always present. Consider the following scenario:

  1. New user launches app, is presented with the LoginForm.
  2. User enters credentials and proceeds to the Home screen.
  3. At the Home screen, clicks the "Back" button.
  4. The user will be sent back to the LoginForm even though they already authenticated.
There is another scenario going the other way:
 
  1. Authenticated user clicks the "Logout" button on Home screen and sent the LoginForm.
  2. On the LoginForm, the user clicks the "Back" button.
  3. The user will be sent back to the Home screen even though they are no longer authenticated.
To handle this special case, we can add a property to the Home and LoginForm windows which will tell the Android app to exit when the window is closed when the "Back" button is clicked. This is done by adding the "exitOnClose" property to the Window tag in the Alloy markup as such:

snippet from file: /app/views/Home.xml
   <Window id="home" layout="vertical" exitOnClose="true">

Open in new window


Snippet from file: /app/views/LoginForm.xml
   <Window id="loginForm" layout="vertical" exitOnClose="true">

Open in new window

1
2,100 Views

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.