Save Login in Flash and Flex

One of the benefits of creating your login in HTML is the browsers ability to save your username and password. This feature is becoming more important with new features like Firefox Sync, Chrome Sync and so on. We can do this in Flash and Flex with a little bit of work.

First, some common promptsĀ  you’ll recognize.

Firefox save password

Safari save password

Google Chrome save password

To begin we need to add a form to your index.template.html page inside the body tag:

	<form id="bridgeForm" action="#" target="loginframe" autocomplete="on" style="display:none">
		<input type="text"     name="username" id="username" />
		<input type="password" name="password" id="password"/>
	</form>

	<iframe id="loginframe" name="loginframe" src="blankpage.html" style="display:none"></iframe>

This gives the browser a form to auto fill and gives us a method to get and set the form values.

The browser will fill the form with values if the user logged in before. If there are multiple users it will fill it with the last user. Or on some browsers it will fill in the password when a saved username is entered into the form.

For this to work with Flash we need to do the following:

1. Add scripts to the page when the application loads (or embed them on the page)
2. Check for existing form values set by the browser
3. Fill in our Flash form with those values

Using the save password class we can perform these procedures.

protected function application_applicationCompleteHandler(event:FlexEvent):void
{
	var savePassword:SavePassword = new SavePassword();
	var savePasswordCreated:Boolean = savePassword.initialize(); // places our javascript onto the page
	var result:Object = savePassword.resizeApplication("60%"); // used to see the form - for testing purposes
	var result2:Object = savePassword.showForm(); // used to see the form - for testing purposes
	var loginItems:Array = savePassword.getFormValues(); // gets existing form values

	if (loginItems.length>0) {
		usernameTextInput.text = loginItems[0];
		passwordTextInput.text = loginItems[1];
	}
}

Before the browser will fill in our form we have to prompt it to save the form. To do this we need to submit the form.

That means doing the following:
4. Copy our login information to the form on the HTML page
5. Submit the form. By default a form will redirect to a new page. We can prevent this by targeting a frame or posting to a hash tag (action=”#”). We are going to target a frame.
6. After calling submit form we can continue to handle the login procedure as normal.

IE we continue to use HTTPService, URLRequest, etc as normal.

protected function submitForm_clickHandler(event:MouseEvent):void
{
	var savePassword:SavePassword = new SavePassword();
	var setValues:Boolean = savePassword.setFormValues(usernameTextInput.text, passwordTextInput.text);
	var results:Boolean = savePassword.submitForm(); // this prompts the save password dialog

	// handle actual validation and login as usual
	myLoginService.send();
}

And our MXML form:

<s:BorderContainer horizontalCenter="0" verticalCenter="0" 
				   width="250"
				   dropShadowVisible="true"
				   >
	<s:layout>
		<s:VerticalLayout paddingBottom="8" paddingLeft="12"
						  paddingRight="8" paddingTop="12"/>
	</s:layout>
	<s:Label text="Login Form" fontSize="24" fontFamily="Verdana"/>
	<s:TextInput id="usernameTextInput" text="" prompt="Username"/>
	<s:TextInput id="passwordTextInput" text="" displayAsPassword="true" prompt="Password"/>
	<s:HGroup>
		<s:Button label="Submit" click="submitForm_clickHandler(event)" />
	</s:HGroup>
</s:BorderContainer>

View ExampleSource CodeLibrary

Optional Multiple Account support
On all of the major browsers if you type into the username field the auto complete will fill in the rest of the username or password. When multiple users are saved for the same site the browsers save the last one submitted and fills the form in with that one on future visits.

If the form is left blank or other events happen the browser may not fill in the form. Usually logging in once will retain that login. If we are using Firefox we can get it to help us auto complete the form when the user types in the username. Other browsers are not as forthcoming.

To do this we need to:
7. Give the HTML form our username and “tab” to the next field
8. Check if the browser has filled in the password after username is entered
9. Fill in our password field with the password

protected function username_focusOutHandler(event:FocusEvent):void
{
	var savePassword:SavePassword = new SavePassword();

	// if username or password is blank check for password after supplying username
	// only am able to get this to work with Firefox at the moment 
	// not thoroughly attempted with other browsers (limited time)
	var value:String = savePassword.checkForPassword(usernameTextInput.text);

	if (value!="") {
		passwordTextInput.text = value;
		passwordTextInput.selectAll();
	}

	// set focus on our text field
	passwordTextInput.setFocus();

	// we have to focus back on Flash because of the javascript we use
	var results:Object = savePassword.setFocusOnFlash();

}

In conclusion, we want our Flex and Flash apps to provide the best experience as possible.

Notes
In Safari it seems that you have to be on a server (localhost or remote) for the passwords to be saved. Firefox has a few minor quirks as well as Chrome but I can’t remember them now. It mainly had to do with making sure the HTML form had all the required elements. Any issues bring them up in the comments and it might jog my memory.

PS This is a work in progress. Please leave your comments or improvements.

This entry was posted in Flash, Flex, HTML. Bookmark the permalink.

8 Responses to Save Login in Flash and Flex

  1. Tahir Ahmed says:

    Just curious! can’t we simply store the form values in SharedObject as cookies and in our interface, we provide the user an option to save it or clear it?

    - Tahir.

    • Judah says:

      Hi Tahir – We can. What this aims to solve is the situation where you have multiple devices or computers. When you go to another computer you no longer have that login stored anywhere since Shared Objects are local to the computer or device. With browsers like Firefox we can opt-in to store our logins across devices. This is where the advantage comes in.

  2. Assaf says:

    Thanks. Very helpful. Not being able to properly fill credentials for users is the number one reason we keep logins in HTML. LastPass, for example, was able to save the credentials in the example app after logging in the first time, but then wasn’t triggered in subsequent page loads. So there’s still some work that can be done. But anyway this is already huge progress.

  3. Rytis says:

    For me it actualy looks like a nasty security hole in all browsers.

    • Judah says:

      Thanks for your feedback. It may look like it but it’s no different than any other website that has a login form. Let me explain. When a user visits your site or web application and there is a form on it, the browser in most cases will ask them if they want to save their login. The user then gives the browser permission to store that login for future visits. Essentially, they’re creating a contract between themselves and the browser that they trust this domain and they would like the browser to fill in the form. The site, regardless of the technology used (HTML, JavaScript, Flash, etc) is offering a service and requires the login form filled in with a valid login to proceed. It doesn’t care if the browser fills it in for the user or the user types it in themselves. At this stage in the sequence of events our site is already approved by the user. None of this happens without that. From then on whether our form is in HTML or Flex we’ll take either. :) It’s about creating a great experience for the user.

  4. Wilson Silva says:

    This is such a good idea!

Leave a Reply

Your email address will not be published. Required fields are marked *

Wrap your code before posting! Click the links below:

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="">