ExtJS: Login with 'Remember me' functionality

Chau picture Chau · May 31, 2010 · Viewed 11.9k times · Source

I'm trying to create a simple login window with the very common 'Remember me' functionality. The login validation is done AJAX style, thus the browser won't remember my input.

My approach is to use the built-in state functionality, but how to use it confuses me.

Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
    expires: new Date(new Date().getTime()+(1000*60*60*24*7)), //7 days from now
}));

...

{
    xtype: 'textfield',
    fieldLabel: 'User name',
    id: 'txt-username',
    stateful: true,
    stateId: 'username'
}, {
    xtype: 'textfield',
    fieldLabel: 'Password',
    id: 'txt-password',
    inputType: 'password',
    stateful: true,
    stateId: 'password'
}, {
    xtype: 'button',
    text: 'Validate',
    stateEvents: 'click'
}

I know I have to implement the getState method, but on what component (my guess is on the two textfields)? Another thing I fail to realize is, how is my click event on the button connected to the state properties of my textfields?

Answer

owlness picture owlness · May 31, 2010

Don't use state. You are storing the user's password in plain text in the browser's cookies. Anyone who has access to the browser can read it and it is being sent back to the server in every request.

Hopefully you are using some form of server-side sessions and are not depending on the user's authentication information being present in every request to maintain logged-in state. If so, then I recommend taking advantage of the password saving feature built in to most modern browsers to handle remembering of the user for the initial authentication in any given session.

For the browser's password saving feature to work the authentication form must be present in the document when the page is first loaded. Also, the credentials must be submitted by that form in a traditional (non-AJAX) submit which will refresh the entire page.

You can fulfill these requirements while still presenting the form in the ExtJS UI by initially rendering the form hidden into the document and then using the capabilities of ExtJS to commandeer existing HTML elements.

In the document's body put:

<form id="auth-form" action="/url/of/your/login/action" method="POST">
    <input id="auth-username" type="text" name="username" class="x-hidden">
    <input id="auth-password" type="password" name="password" class="x-hidden">
    <input id="auth-submit" type="submit" class="x-hidden">
</form>

Then, in Ext.onReady or at the time you are displaying an authentication form build a panel which makes use of the above form elements:

new Ext.Panel({
    el: 'auth-form',
    autoShow: true,
    layout: 'form',
    items: [
        {
            xtype: 'textfield',
            el: 'auth-username',
            autoShow: true,
            name: 'username',
            fieldLabel: 'Username',
            anchor: '100%'
        },
        {
            xtype: 'textfield',
            el: 'auth-password',
            autoShow: true,
            name: 'password',
            fieldLabel: 'Password',
            anchor: '100%'
        }
    ],
    buttons: [
        {
            text: 'Log in',
            handler: function() {
                Ext.get('auth-submit').dom.click();
            }
        }
    ]
});

The exact composition of the form may vary. It may be built into an Ext.Window instance or whatever else. What is important:

  • The username and password fields make use of the existing input fields through the 'el' and 'autoShow' config properties.
  • One of the panels containing the fields does the same for the existing form element.
  • The submission of the form is performed by a simulated click on the existing submit button.