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

});