Sencha Touch auto login example

If you are creating a native application using Sencha Touch then most likely your users may expect the app to stay logged in unless they manually take an action to logout as mobile devices are considered kind of personal and they have a lock screen of their own. In this example we take advantage of the local storage that is available to us to keep information about the user session as they login for the first time.

We have sample Java servlet program that does the authentication and sends the session Id if the login was successful. The mobile application will throw the login screen to user for the first time. As they login an ajax request will be made to the backend server which will respond if the request was successful or not and if successful we store the session Id in the local storage. Now the next time user tries to open this app it will first check the local storage if there is any information about session Id and if available it will then take them directly into the home page otherwise just throw the login page.


Sencha Touch auto login example

Application HTML page - autoLogin.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="robots" content="noindex,nofollow"/>
<title>Programmers sample guide, help is on the way</title>
<link rel="stylesheet" href="/sencha-touch/resources/css-debug/sencha-touch.css" type="text/css">
<script type="text/javascript" src="/sencha-touch/sencha-touch-all-debug.js"></script>
<script type="text/javascript">

Ext.Loader.setConfig({ 
 enabled: true 
});

Ext.application({
    
 name: 'MyApp',
 appFolder: '/Sencha_Touch/app/autoLogin',
 
 requires: [
               'MyApp.view.MainNavigation'
               ], 
               
    views : ['MainNavigation'],           
    controllers: ['AutoLoginDemo'],
    
    launch: function() {
     console.log('Application launch');
     Ext.create('Ext.Container', {
      fullscreen: true,
      layout: 'vbox',
         items: [{
          flex: 1,
          xtype: 'mainNavigation'
            }]
     });
    }
    
});

</script>
</head>

<body>
</body>
</html>

Model for the session storage - SessionInfo.js

Ext.define('MyApp.model.SessionInfo', {
    extend: 'Ext.data.Model',
    config: {
     identifier: 'uuid',
     fields: [
              'sessionId'
              ]
    }
});

Store for the session storage - SessionInfo.js

Ext.define('MyApp.store.SessionInfo', {
    extend: 'Ext.data.Store',
    
    config: {
        model: 'MyApp.model.SessionInfo',
        autoLoad: true,
         
        proxy: {
         type: 'localstorage',
         id  : 'myApplicationKey'
        }
    }
});

Navigation view for our application - MainNavigation.js

Ext.define('MyApp.view.MainNavigation', {
    extend: 'Ext.navigation.View',
    alias : 'widget.mainNavigation',
    id: 'mainNavigation',
    
    requires: [
               'MyApp.view.Home',
               'MyApp.view.Login'
               ], 
    
    config: {
        
     navigationBar: {
            ui: 'dark',
            items: [{
                xtype: 'button',
                id: 'logoutUser',
                text: 'Logout',
                align: 'right',
                hidden: true,
                hideAnimation: Ext.os.is.Android ? false : {
                    type: 'fadeOut',
                    duration: 200
                },
                showAnimation: Ext.os.is.Android ? false : {
                    type: 'fadeIn',
                    duration: 200
                }
            }]
        },
        
        items: [{
         title: 'Home',
            items: [{
                xtype: 'login',
                flex: 1
            },{
                xtype: 'homePage',
                flex: 1,
                hidden: true
            }]
        }]
    }
    
  
});

View for the login page - Login.js

Ext.define('MyApp.view.Login', {
    extend: 'Ext.form.Panel',
    alias : 'widget.login',
    
    config: {
     
     title: 'Home',
     height: 300,
     layout: {
            type: 'vbox',
        },
        defaults: {
            margin: '0 0 5 0'
        },
        items: [
            {
             xtype: 'fieldset',
                title: 'User Authentication',
                items: [
                    {
                        xtype: 'textfield',
                        label: 'User Id',
                        itemId: 'userId',
                        name: 'userId',
                        allowBlank: false,
                        autoCapitalize: false,
                        labelWidth: 100
                    },
                    {
                        xtype: 'passwordfield',
                        label: 'Password',
                        itemId: 'password',
                        name: 'password',
                        allowBlank: false,
                        labelWidth: 100
                    }
                ]
   },   
   {
                xtype: 'button',
                itemId: 'loginButton',
                text: 'Login',
                ui: 'action'
            }
        ]
    }
  
});

View for the home page - Home.js

Ext.define('MyApp.view.Home', {
    extend: 'Ext.Panel',
    alias : 'widget.homePage',
    
    config: {
     
     title: 'Home',
     layout: {
            type: 'vbox',
        },
        defaults: {
            margin: '5 5 5 5'
        },
  
        items: [{
            xtype: 'panel',
            id: 'welcomePanel',
            html: 'Welcome',
            margin: '5 5 20 5'
        }]
    }
  
});

Finally the application controller - AutoLoginDemo.js

Ext.define('MyApp.controller.AutoLoginDemo', {
 extend : 'Ext.app.Controller',

 sessionId: null,
 
 config: {
  profile: Ext.os.deviceType.toLowerCase(),
  stores : ['SessionInfo'],
  models : ['SessionInfo'],
  
  refs: {
   myNavigationView: 'mainNavigation',
   myLoginPanel: 'login'
  },
  
  control: {
   'login button[itemId=loginButton]' : {
    tap : 'onUserAuthentication' 
   },
   'mainNavigation button[itemId=logoutUser]' : {
    tap : 'onUserLogout' 
   }
  }  

 },
 
 launch: function() {
     console.log('Launch for controller');
     var sessionInfo = Ext.getStore('SessionInfo');             
     if(null!=sessionInfo.getAt(0)){
      this.successfulLogin(sessionInfo.getAt(0).get('sessionId'));
        }
     
    },
    
    onUserAuthentication: function(button) {
     var fieldset = button.up('panel').down('fieldset');
     var userId = fieldset.getComponent('userId');
     var password = fieldset.getComponent('password');
     if(userId.getValue() && password.getValue()){
      
      button.setText('Please wait ...');
      button.setDisabled(true);
      
      Ext.Ajax.request({
             url : '../Login',
             method:'POST', 
             params : {
                 userId: userId.getValue(),
                 password: password.getValue()
             },
             scope : this,
             //method to call when the request is successful
             success : this.onLoginSuccess,
             //method to call when the request is a failure
             failure : this.onLoginFailure
      }); 
      
      password.setValue('');
      
     }
     else {
      Ext.Msg.alert('', 'Please enter User Id and/or Password', Ext.emptyFn);
       }
    },
    
    onUserLogout: function(button) {
     
     this.sessionId = null;
     var sessionInfo = Ext.getStore('SessionInfo');
     sessionInfo.removeAll();
     sessionInfo.sync();
     
     var logoutButton = Ext.getCmp('logoutUser');
     logoutButton.setHidden(true);
     
     var navigationView = this.getMyNavigationView();
     var loginPanel = navigationView.down('login');
  var homePage = navigationView.down('homePage');
  loginPanel.show(true);
  homePage.hide(true);
    },
    
    onLoginFailure : function(err) {
     
     var panel = this.getMyLoginPanel();
     var button = panel.getComponent('loginButton');
     button.setText('Login');
  button.setDisabled(false);
     
  Ext.Msg.alert('', 'Error connecting to server, please try after some time', Ext.emptyFn);
    },

    onLoginSuccess : function(response, opts) {
     
     var panel = this.getMyLoginPanel();
     var button = panel.getComponent('loginButton');
     button.setText('Login');
  button.setDisabled(false);
  
        response = Ext.decode(response.responseText);
        if(response.success){
         this.successfulLogin(response.sessionId);
        }
        else {
            Ext.Msg.alert('Login failed', response.message);
        }
    },

    successfulLogin: function(sessionId){
     
     this.sessionId = sessionId;
     
     var sessionInfo = Ext.getStore('SessionInfo');
     sessionInfo.removeAll();
     sessionInfo.sync();
     var newRecord = new MyApp.model.SessionInfo({
      sessionId: this.sessionId 
     });
     sessionInfo.add(newRecord);
     sessionInfo.sync();
     
     var navigationView = this.getMyNavigationView();
     var loginPanel = navigationView.down('login');
     var homePage = navigationView.down('homePage');
     var myHtml = "Welcome, <b>You are now logged in...</b>";
     Ext.getCmp('welcomePanel').setHtml(myHtml);
     loginPanel.hide(false);
     homePage.show(false);
     
     var logoutButton = Ext.getCmp('logoutUser');
     logoutButton.setHidden(false);
     
    },
    
 init: function() {
  console.log('Controller initialized');
 }

});


8 comments :

  1. Good tutorial! thanks! by the way, how what do i type in the url?
    Ext.Ajax.request({
    url : '../Login',

    ReplyDelete
  2. Excellent tutorial! Any chance you would be so kind to publish the login code at server side please? Thank you!

    ReplyDelete
  3. Thanks for the tutorial. Can you post the code for the login at the server side please?

    ReplyDelete
  4. Hi I am getting some "Uncaught TypeError: Cannot call method 'getValue' of undefined " at line 40 in AutoLoginDemo.js , don't know why Can you please explain...

    ReplyDelete
  5. THANKS SO MUCH. CAN YOU SHOW US THE SERVER SIDE AS WELL? THIS IS REALLY HELPFUL

    ReplyDelete
  6. Thanks you, it helped me a lot !

    ReplyDelete
  7. Thx for the tutorial :)

    Just one thing though. I think that this approach makes a false assumption and the assumption is that the session nevers expires. If the server expires the session, the app will still find the now obsolete session id inside the local storage and will present the user with the navigation view instead of the login one.

    ReplyDelete
  8. There was once a time when I also deemed that we began to lose our direction cheap fifa 14 coins and become numb without too much affection in this material-flooding world. We were not sure whether the reason why we locked tightly our heart was to eliminate loneliness fifa 14 coins or to protect ourselves. We did it unconsciously with less and less emotion and smile. So someone said that I was awfully icy to others. Not until one day when I was stricken by a sense of gratitude cheap fifa 14 coins did I totally change myself.

    ReplyDelete