Remembering Authentication Details in AIR with EncryptedLocalStore

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);
    }
}

This site uses cookies. Continue to use the site as normal if you are happy with this, or read more about cookies and how to manage them.

X