Minggu, 15 Mei 2011

Creating "Keep Login" in Adobe FLEX/AIR application using ticlib

Problems
  1. Persisting user login state in shared object using flex SharedObject isn't quite natural.
  2. Security issue, in fact sol object is easy to edit. So unauthorized user can fake login to the website.

Requirements
  1. ticlib
  2. as3core
  3. Download example source code


SimpleConfiguration
ticlib SimpleConfiguration provide an easy and natural way to persist object state to shared object. The only you need to do is add [Config] annotation in the variable or getter of a class then saveConfiguration() method will automatically save its state and loadConfiguration() will reload its current state.

[Bindable]
public class LoginModel
{
 [Config]
 public var userName:String;
 public var password:String;
 public var keepLogin:Boolean = true;
 [Config]
 public var loginTokken:String;
}

You are freely to assign default value for any variable marked as [Config]

Securing user login information
Login state easily faked by unauthorized user when using unencrypted data, whereas some type saved in plain text in shared object.
The easies way to save login user state is by using hash key, which is the login key should contains information about current user, thus when username manually changed in shared object the hash key didn't match with the actual value.
In login model above hash key will be saved on loginToken field.

if(model.userName == "user" && model.password == "user"){
 if(model.keepLogin){
  model.loginTokken = ScurityModel.generateLoginToken(model.userName);
  SimpleConfigration.saveConfiguration(model);
 }
 
 dispatchEvent(new Event("loginSuccess"));
}

Snippet above showing that when keepLogin is checked by user loginTokken calculated by ScurityModel class then SimpleConfiguration class will persist the state to shared object. easy? yes sure.
Lets take a deep look at what happen in generateLoginToken method

public class ScurityModel
{
 public static const TOKEN:String = "ff3ac8dfac32ff5686a88c76f89a7";

 public static function generateLoginToken(userName:String):String{
  var token:String = StringUtil.substitute("{0}-{1}",
   userName, TOKEN);
  return SHA256.hash(token);
 }
}

Not really complicated huh? we just make make a really random string containts username, than make hash code from it. you can provide more secure way if you don't like this trick.
Remember to check weather the loginToken is already persisted or not.

SimpleConfigration.loadConfiguration(model);
if(model.loginTokken == ScurityModel.generateLoginToken(model.userName))
 dispatchEvent(new Event("loginSuccess"));
model.userName = "";

To log out you only need to clear the loginTokken field than persist it back to shared object.

var mdl:LoginModel = new LoginModel();
SimpleConfigration.loadConfiguration(mdl);
mdl.loginTokken = "";
mdl.userName = "";
SimpleConfigration.saveConfiguration(mdl);
dispatchEvent(new Event("logout"));

Thats all you need to do, using ticlib you can presist your model state by only using [Config] annotation, without having to care about how the process actually done. Happy coding!