Black Pepper Blog

The thoughts and musings of our team


Giving users the option to have your application remember their login details is a simple and really useful feature for any desktop app to offer. Web browsers have had this feature for a long time now and you can even store your usernames for your Flex web app in a SharedObject...but when storing passwords, you have to be quite careful with how you store the data.

Thankfully EncryptedLocalStore comes to the rescue in AIR, but it's not available in the browser.

My test app for this is a simple two screen Cairngorm AIR app. I'll skip over some of the boilerplate of the app and just get down to the nitty gritty.

 
public function resultHandler(event:ResultEvent, token:AsyncToken) : void {
      var user:CfxUser = event.result as CfxUser;
 
      if (ModelLocator.instance.rememberMe) {
        var usernameBytes:ByteArray = new ByteArray();
        usernameBytes.writeUTFBytes(ModelLocator.instance.credentials.username);
        var passwordBytes:ByteArray = new ByteArray();
        passwordBytes.writeUTFBytes(ModelLocator.instance.credentials.password);
 
        EncryptedLocalStore.setItem(USERNAME_KEY, usernameBytes);
        EncryptedLocalStore.setItem(PASSWORD_KEY, passwordBytes);
      }
 
      ModelLocator.instance.userDetails = user;
      new ChangeScreenEvent(ScreenManager.DASHBOARD_VIEW).dispatch();
 
    }
 

This resultHandler is called when a successful login has been performed against my remote login service. Before the login was performed, I stored the username/password in the ModelLocator for later use. I also stored if the user ticked the remember me checkbox. If they did, then we simply create a new ByteArray for each of the username and password and write the data to each and then set the username and password data under a known key in the ELS. I can then continue on as a logged in user to the dashboard screen.

Now that is all fine and well for storing the data...how do you get it back out and automatically log someone in?

 
public function execute(event:CairngormEvent):void {
  var usernameBytes:ByteArray = EncryptedLocalStore.getItem(USERNAME_KEY);
  if (usernameBytes) {
    logUserInFromELS(usernameBytes);
  } else {
    new ChangeScreenEvent(ScreenManager.LOGIN_VIEW).dispatch();
  }
}
 
private function logUserInFromELS(usernameBytes:ByteArray) : void {
  var passwordBytes:ByteArray = EncryptedLocalStore.getItem(PASSWORD_KEY);
  var storedUsername:String = usernameBytes.toString();
  var storedPassword:String = passwordBytes.toString();
  new LoginEvent(storedUsername, storedPassword, true).dispatch();
}
 

The app starts up and the execute() gets called, we now either login the user from the ELS or redirect them off to the login screen. Simple.

Now, we can also clear the store when a user explicitly logs out.

 
public class LogoutCommand implements ICommand
{
  public function execute(evt:CairngormEvent):void
  {
    var event:LogoutEvent = evt as LogoutEvent;
    ModelLocator.instance.credentials.password = "";
    ModelLocator.instance.credentials.username = "";
 
    EncryptedLocalStore.removeItem(LoginCommand.USERNAME_KEY);
    EncryptedLocalStore.removeItem(LoginCommand.PASSWORD_KEY);
 
    ModelLocator.instance.screenManager.goToScreen(ScreenManager.LOGIN_VIEW);      
  }    
}
 

Comments (2)Add Comment
Doug Hovey
October 16, 2009
141.211.117.83
Votes: +0
...

So my situation is that I need the user to have to log in to the AIR app even when they are not connected to the http server. If they are, great, they go and authenticate that way. But if they take their laptop offline and to a client, it still has to be secured. Is this the way to do it?

Adam13
February 10, 2010
194.242.102.250
Votes: +0
Write comment
 
  smaller | bigger
 

security image
Write the displayed characters


busy