Adding a Login Screen to a Sencha Touch Application, Part 2

In this second part of my tutorial on How to add a Login Screen to Sencha Touch application, you will continue building a small Sencha Touch app that demonstrates how to implement a very basic login feature.

You created the app’s Login view with its main components in the first part of the tutorial, and gave the Login view the ability to fire the signInCommand application event when a user taps the Login button.

Creating the MainMenu View

Now you will create the app’s MainMenu view. You will take users to this view after a successful authentication.

You need to place the view’s code in the view/MainMenu.js file. Here is the skeleton of the view:

Ext.define('Sample.view.MainMenu', {
    extend: 'Ext.Panel',
    requires: ['Ext.TitleBar'],
    alias: 'widget.mainmenuview',
    config: {
        layout: {
            type: 'fit'
        },
	 items:[]
    }
});

To keep this tutorial as simple as possible, the MainMenu view will contain just a TitleBar, which in turn will host the LogOff button. You need to add these components in the view’s items array:

items: [{
    xtype: 'titlebar',
    title: 'Main Menu',
    docked: 'top',
    items: [
        {
            xtype: 'button',
            text: 'Log Off',
            itemId: 'logOffButton',
            align: 'right'
        }
    ]
}]

The LogOff button needs a tap listener, which you will define in the listeners config:

listeners: [{
    delegate: '#logOffButton',
    event: 'tap',
    fn: 'onLogOffButtonTap'
}]

Inside this listener, you will trigger an application event called signOffCommand:

onLogOffButtonTap: function () {
    this.fireEvent('signOffCommand');
}

The controller will capture this event and perform the log off logic.

This is all you will do in the MainMenu view (In a real-world app, you will need to add more components to this view). Now you need to add the view in the app.js file:

Ext.application({
    name: 'Sample',
    views: ['Login','MainMenu'],
    controllers:['Login'],
    launch: function () {

        Ext.Viewport.add([
            { xtype: 'loginview' },
            { xtype: 'mainmenuview' }
        ]);
    }
});

Creating the Controller

The next application module you will create is the Login controller. Inside the controller, you will handle the signInCommand event, and create the logic to authenticate the user and grant her access to the application’s main menu Screen.

The controller will also handle the signOffCommand event, triggered by the MainMenu view when the user has requested to log off.

Let’s start with an empty controller in the controller/Login.js file:

Ext.define('Sample.controller.Login', {
    extend: 'Ext.app.Controller',
    config: {

    }
});

Since you want to listen to events generated in the Login and MainMenu views, you need to create their respective references in the controller. You will create the loginView and mainMenuView references using the controller’s refs config:

Ext.define('Sample.controller.Login', {
    extend: 'Ext.app.Controller',
    config: {
        refs: {
            loginView: 'loginview',
            mainMenuView: 'mainmenuview'
        },
        control: {
            loginView: {
                signInCommand: 'onSignInCommand'
            }
        }
    }
});

The control config is where you define the events you want your controller to listen to. In this case, you are saying that the signInCommand generated by the Login view ref will be handled by the onSignInCommand method.

Implementing the Sign-in Logic

The onSignInCommand method is in charge of performing the authentication logic:

onSignInCommand: function (view, username, password) {

    console.log('Username: ' + username + '\n' + 'Password: ' + password);

    var me = this,
        loginView = me.getLoginView();

    if (username.length === 0 || password.length === 0) {

        loginView.showSignInFailedMessage('Please enter your username and password.');
        return;
    }

    loginView.setMasked({
        xtype: 'loadmask',
        message: 'Signing In...'
    });

    Ext.Ajax.request({
        url: '../../services/login.ashx',
        method: 'post',
        params: {
            user: username,
            pwd: password
        },
        success: function (response) {

            var loginResponse = Ext.JSON.decode(response.responseText);

            if (loginResponse.success === "true") {
                // The server will send a token that can be used throughout the app to confirm that the user is authenticated.
                me.sessionToken = loginResponse.sessionToken;
                me.signInSuccess();     //Just simulating success.
            } else {
                me.signInFailure(loginResponse.message);
            }
        },
        failure: function (response) {
            me.sessionToken = null;
            me.signInFailure('Login failed. Please try again later.');
        }
    });
}

Inside onSignInCommand, you first perform a very simple validation of the username and password values passed by the Login view:

var me = this,
    loginView = me.getLoginView();

if (username.length === 0 || password.length === 0) {

    loginView.showSignInFailedMessage('Please enter your username and password.');
    return;
}

If the validation fails, you will invoke the Login view’s showSignInFailedMessage method. This method does not exist yet. Let’s jump to the view/Login.js file and add it like so:

showSignInFailedMessage: function (message) {
    var label = this.down('#signInFailedLabel');
    label.setHtml(message);
    label.show();
}

In showSignInFailedMessage, you acquire a reference to the label component you will use to display the failure message, and set its html to the value passed from the controller. Invoking this method when the validation fails will change the look of the view as depicted below:

login-view-11

Back in the controller/Login.js file, your next step inside the onSignInCommand method consists of activating the Login view’s load mask. You can accomplish this using the setMasked method:

loginView.setMasked({
    xtype: 'loadmask',
    message: 'Signing In...'
});

Next, you will send the username and password values to the server for authentication:

Ext.Ajax.request({
    url: '../../services/login.ashx',
    method: 'post',
    params: {
        user: username,
        pwd: password
    },
    success: function (response) {

        var loginResponse = Ext.JSON.decode(response.responseText);

        if (loginResponse.success === "true") {
            // The server will send a token that can be used throughout the app to confirm that the user is authenticated.
            me.sessionToken = loginResponse.sessionToken;
            me.signInSuccess();     //Just simulating success.
        } else {
            me.signInFailure(loginResponse.message);
        }
    },
    failure: function (response) {
        me.sessionToken = null;
        me.signInFailure('Login failed. Please try again later.');
    }
});

You are making an Ajax request, sending the username and password to the server through the params config. You are free to use any server-side technology. Just make sure to change the url config so it references the endpoint that will perform the authentication in your app.

The success callback evaluates the server’s response and sets the controller’s sessionToken property. You can use this property throughout the app to confirm that the user is authenticated. After setting the session token, the callback invokes either the signInSuccess or signInFailure methods in the controller.

The failure callback invokes the controller’s signInFailure method after cancelling the session token.

Let’s implement the signInSuccess method first:

signInSuccess: function () {
    console.log('Signed in.');
    var loginView = this.getLoginView();
    mainMenuView = this.getMainMenuView();
    loginView.setMasked(false);

    Ext.Viewport.animateActiveItem(mainMenuView, this.getSlideLeftTransition());
}

Inside signInSuccess, you need to turn off the Login view’s mask, and make the MainMenu view active. Here you will take advantage of the getLoginView and getMainMenuView methods, which the framework creates for you automatically when you add the views’ references in the ref config of the controller.

When making the MainMenu view active, you will use of the getSlideLeftTransition method. This method returns a slide left transition object that you can use in the controller:

getSlideLeftTransition: function () {
    return { type: 'slide', direction: 'left' };
}

The MainMenu view should look like this:

main-menu-view1

Now you can go ahead and create the signInFailure method. This method will let the user know that the sign in operation failed. Let’s take a look at the code:

signInFailure: function (message) {
    var loginView = this.getLoginView();
    loginView.showSignInFailedMessage(message);
    loginView.setMasked(false);
}

This short method invokes a couple of routines in the Login view: showSignInFaileMessage and setMasked. You have used both methods previously in this tutorial.

This is all you need to handle the success and failure cases in the sign in logic. Now you can focus on the sign off logic.

Implementing the Sign-off Logic

The first step would be to handle the signOffCommand fired from the MainMenu view. In the control section of the controller’s config, you will add an entry for the MainMenu view:

config: {
    refs: {
        loginView: 'loginview',
        mainMenuView: 'mainmenuview'
    },
    control: {
        loginView: {
            signInCommand: 'onSignInCommand'
        },
        mainMenuView: {
            signOffCommand: 'onSignOffCommand'
        }
    }
}

The entry maps the signOffCommand event to a controller method named onSignOffCommand. You can add the onSignOffCommand method at the end of the controller:

onSignOffCommand: function () {

    var me = this;

    Ext.Ajax.request({
        url: '../../services/logoff.ashx',
        method: 'post',
        params: {
            sessionToken: me.sessionToken
        },
        success: function (response) {

            // TODO: Implementation.
        },
        failure: function (response) {

            // TODO: Implementation.
        }
    });

    Ext.Viewport.animateActiveItem(this.getLoginView(), this.getSlideRightTransition());
}

You need to expire the user’s session on both the server and the client. This is why you are first executing an Ajax request to the server-side endpoint responsible for expiring the user’s token on the server, and then cancelling the token in the app.

After these steps, you will make the Login view active again. Here you will use the getSlideRightTransition method, which returns a slide right transition as its name indicates:

getSlideRightTransition: function () {
    return { type: 'slide', direction: 'right' };
}

Conclusion

In this tutorial you learned how to add a Login view to a Sencha Touch application. You also learned how to connect this view to a controller that performs authentication logic on behalf of the application.

Authentication is only one part of the security design of an app. After authentication takes place, you need to decide which application features the user will be able to access based on her rights. In future tutorials I will touch on this subject, commonly known as authorization, and how you can implement it in a Sencha Touch app.

Stay Tuned

Don’t miss the next article. Get free updates in your inbox.



MiamiCoder will never sell your email address.

Source Code

Here’s the source code of the app.

App.js:

Ext.application({
    name: 'Sample',
    views: ['Login','MainMenu'],
    controllers:['Login'],
    launch: function () {

        Ext.Viewport.add([
            { xtype: 'loginview' },
            { xtype: 'mainmenuview' }
        ]);
    }
});

view/Login.js:

Ext.define('Sample.view.Login', {
    extend: 'Ext.form.Panel',
    alias: "widget.loginview",
    requires: ['Ext.form.FieldSet', 'Ext.form.Password', 'Ext.Label', 'Ext.Img', 'Ext.util.DelayedTask'],
    config: {
        title: 'Login',
        items: [
            {
                xtype: 'image',
                src: Ext.Viewport.getOrientation() == 'portrait' ? '../../../img/login.png' : '../../../img/login-small.png',
                style: Ext.Viewport.getOrientation() == 'portrait' ? 'width:80px;height:80px;margin:auto' : 'width:40px;height:40px;margin:auto'
            },
            {
                xtype: 'label',
                html: 'Login failed. Please enter the correct credentials.',
                itemId: 'signInFailedLabel',
                hidden: true,
                hideAnimation: 'fadeOut',
                showAnimation: 'fadeIn',
                style: 'color:#990000;margin:5px 0px;'
            },
            {
                xtype: 'fieldset',
                title: 'Login Example',
                items: [
                    {
                        xtype: 'textfield',
                        placeHolder: 'Username',
                        itemId: 'userNameTextField',
                        name: 'userNameTextField',
                        required: true
                    },
                    {
                        xtype: 'passwordfield',
                        placeHolder: 'Password',
                        itemId: 'passwordTextField',
                        name: 'passwordTextField',
                        required: true
                    }
                ]
            },
            {
                xtype: 'button',
                itemId: 'logInButton',
                ui: 'action',
                padding: '10px',
                text: 'Log In'
            }
         ],
        listeners: [{
            delegate: '#logInButton',
            event: 'tap',
            fn: 'onLogInButtonTap'
        }]
    },
    onLogInButtonTap: function () {

        var me = this,
            usernameField = me.down('#userNameTextField'),
            passwordField = me.down('#passwordTextField'),
            label = me.down('#signInFailedLabel'),
            username = usernameField.getValue(),
            password = passwordField.getValue();

        label.hide();

        // Using a delayed task in order to give the hide animation above
        // time to finish before executing the next steps.
        var task = Ext.create('Ext.util.DelayedTask', function () {

            label.setHtml('');

            me.fireEvent('signInCommand', me, username, password);

            usernameField.setValue('');
            passwordField.setValue('');
        });

        task.delay(500);

    },
    showSignInFailedMessage: function (message) {
        var label = this.down('#signInFailedLabel');
        label.setHtml(message);
        label.show();
    }
});

view/MainMenu.js:

Ext.define('Sample.view.MainMenu', {
    extend: 'Ext.Panel',
    requires: ['Ext.TitleBar'],
    alias: 'widget.mainmenuview',
    config: {
        layout: {
            type: 'fit'
        },
        items: [{
            xtype: 'titlebar',
            title: 'Main Menu',
            docked: 'top',
            items: [
                {
                    xtype: 'button',
                    text: 'Log Off',
                    itemId: 'logOffButton',
                    align: 'right'
                }
            ]
        }],
        listeners: [{
            delegate: '#logOffButton',
            event: 'tap',
            fn: 'onLogOffButtonTap'
        }]
    },
    onLogOffButtonTap: function () {
        this.fireEvent('onSignOffCommand');
    }
});

controller/Login.js:

Ext.define('Sample.controller.Login', {
    extend: 'Ext.app.Controller',
    config: {
        refs: {
            loginView: 'loginview',
            mainMenuView: 'mainmenuview'
        },
        control: {
            loginView: {
                signInCommand: 'onSignInCommand'
            },
            mainMenuView: {
                onSignOffCommand: 'onSignOffCommand'
            }
        }
    },

    // Session token

    sessionToken: null,

    // Transitions
    getSlideLeftTransition: function () {
        return { type: 'slide', direction: 'left' };
    },

    getSlideRightTransition: function () {
        return { type: 'slide', direction: 'right' };
    },

    onSignInCommand: function (view, username, password) {

        console.log('Username: ' + username + '\n' + 'Password: ' + password);

        var me = this,
            loginView = me.getLoginView();

        if (username.length === 0 || password.length === 0) {

            loginView.showSignInFailedMessage('Please enter your username and password.');
            return;
        }

        loginView.setMasked({
            xtype: 'loadmask',
            message: 'Signing In...'
        });

        Ext.Ajax.request({
            url: '../../services/login.ashx',
            method: 'post',
            params: {
                user: username,
                pwd: password
            },
            success: function (response) {

                var loginResponse = Ext.JSON.decode(response.responseText);

                if (loginResponse.success === "true") {
                    // The server will send a token that can be used throughout the app to confirm that the user is authenticated.
                    me.sessionToken = loginResponse.sessionToken;
                    me.signInSuccess();     //Just simulating success.
                } else {
                    me.signInFailure(loginResponse.message);
                }
            },
            failure: function (response) {
                me.sessionToken = null;
                me.signInFailure('Login failed. Please try again later.');
            }
        });
    },

    signInSuccess: function () {
        console.log('Signed in.');
        var loginView = this.getLoginView();
        mainMenuView = this.getMainMenuView();
        loginView.setMasked(false);

        Ext.Viewport.animateActiveItem(mainMenuView, this.getSlideLeftTransition());
    },

    singInFailure: function (message) {
        var loginView = this.getLoginView();
        loginView.showSignInFailedMessage(message);
        loginView.setMasked(false);
    },

    onSignOffCommand: function () {

        var me = this;

        Ext.Ajax.request({
            url: '../../services/logoff.ashx',
            method: 'post',
            params: {
                sessionToken: me.sessionToken
            },
            success: function (response) {

                // TODO: You need to handle this condition.
            },
            failure: function (response) {

                // TODO: You need to handle this condition.
            }
        });

        Ext.Viewport.animateActiveItem(this.getLoginView(), this.getSlideRightTransition());
    }
});

Comments

  1. says

    Nice tutorials.
    Thanks.
    Can you please tell me how we can save the login in session.
    For example after login to the application then if I close the application by clicking the home button and then open it again. I want to see the main menu and not the login screen.
    Any suggestion will be really helpful .

    Thanks for your help
    Joseph

    • says

      Here’s one approach: Make sure you save the user’s token (or session id as some people prefer to call it) on the server side. Add a “remember me” checkbox to the Login view. If the box is checked, save the session token on the client using a cookie. When the app loads again, read the cookie. If the cookie has not expired, the session should still be active.

    • joerg says

      how can I load the app when the values ​​for the password and login to write to the text fields. I use the localstorge and have the values ​​written to a locale variable.

      app.js
      ….
      //globale Variable
      loginname : ”,
      loginpw : ”,


      launch: function () {
      Ext.getStore(‘login_store’).load().each(function(record) {
      login.app.loginname = record.get(‘username’);
      login.app.loginpw = record.get(‘passwort’);
      });

      login.js

      xtype: ‘textfield’,
      value: login.app.loginname, // is empty
      placeHolder: ‘Benutzername’,
      itemId: ‘userNameTextField’,
      name: ‘userNameTextField’,
      required: true,
      ///
      the value login.app.loginname is empty
      I have all listeners but try not to work.
      can you help me?

  2. Andrés Torres says

    Hey Jorge, thank u, but i have a question, how can i do that with a crossdomain?, i have my login view, but i need to connect with other domain to post and get the data, can u give me a example or some help? thank u

  3. patrick says

    i guess the response on failure or success are got from the server side when data is posted to the server side. please i need to know how that response is wrote in php on the sever side. so that there is some thing like a callback and response from the server. thnk you for your tuts they you really rock man!@

    • says

      Here they are. Remember that this is just an example. You will need to add your own authentication and logoff logic:

      public class Login : IHttpHandler
      {
      public void ProcessRequest(HttpContext context)
      {

      string result = “{\”success\”:\”false\”,\”message\”:\”Login failed. Please enter the correct credentials.\”}”;
      string username = context.Request.Form["user"];
      string password = context.Request.Form["pwd"];

      if (// Place your authentication logic here)
      {
      var sessionToken = // Create a session token here;
      result = “{\”success\”:\”true\”,\”message\”:\”\”,sessionToken:” + sessionToken.ToString() + “}”;
      }

      context.Response.ContentType = “application/json”;
      context.Response.Write(result);
      }

      public bool IsReusable
      {
      get
      {
      return false;
      }
      }
      }

      public class Logoff : IHttpHandler
      {
      public void ProcessRequest(HttpContext context)
      {

      string result = “{\”success\”:\”false\”}”;

      if (// Place your log off logic here)
      {
      result = “{\”success\”:\”true\”}”;
      }

      context.Response.ContentType = “application/json”;
      context.Response.Write(result);
      }

      public bool IsReusable
      {
      get
      {
      return false;
      }
      }
      }

      • Sur says

        Hi Jorge,
        i am a newbie in Sencha and i am confused on term login and logoff where are we supposed to store these files?? After successfull login how are we supposed to know login from server.
        Please help me.
        Thank You!

        • says

          After successful login, the server should send a session token or session id to the app. The app will use this to talk to the server going forward so the server can identify to what session the app’s requests belong to. To log off, you need to cancel this session id both on the client and server.

          • Sur says

            how can i parse this
            {“data”:{“token”:”50a3136d949cebb71e421d6e6d5abf21a44b123c”},”status”:”TRUE”,”message”:”successful”,”response_status”:200}

            I tried but unable to do this.

  4. Evan says

    Hi,

    I am getting an undefined when I call getMainmenuview() that gets generated by the ref ‘mainmenuview’.

    Did no one else have this problem? getLoginView() is fine though.

    THanks,
    Evan

    • says

      You are calling getMainMenuView(), correct? Make sure to create the ref for the view. See below:

      Ext.define(‘Sample.controller.Login’, {
      extend: ‘Ext.app.Controller’,
      config: {
      refs: {
      loginView: ‘loginview’,
      mainMenuView: ‘mainmenuview’
      }
      }
      });

      • Edward says

        I have the same problem. I am getting an undefined when I call getMainMenuView() that gets generated by the ref ‘mainmenuview’.

        Calling getLoginView() works well.

        Ref to the view created as described.

        • Chris says

          I’m stuck here too! I have the id MainMenuView set and the refs are set properly. So confused, do you remember how you got past this?

          Thanks in advance!

    • Daniel says

      The problem is not in the refs but in the variable declaration that is missing the keyword var. Bug is at line 78 in controller/Login.js

  5. Ignatius Kiran says

    Hi Jorge, Great tutorial.. really help me to understand things…

    Now if i have to add a Few HTML piece of code.. Like
    I need to have a Hotel search and booking page in Mainview page…
    how can i add html tags or how do i do it apart from the default components of sencha…

    Plz suggest

    • says

      One approach would be to use container components, each with a template that you can use to define your custom html. Another approach would be to use a template for the entire “content” area of the view, except the toolbar.

  6. Afnan says

    hi
    i’m having trouble creating a login page with PHP back_end
    i can’t find any tutorial that can help me and im getting very frustrated. can you please explain to me how to send response from php and process in client side ?

  7. says

    Jorge,

    LOVE this tute. Thank you for sharing. I’m bolting login and registration components onto a project and this has been immensely helpful.

    Having issues firing the signInCommand function on the tap event… I’m sure I can figure it out – if I could get sencha working in firefox – so that I can use the console… this is my first sencha app… are there any additional tools or tricks that you use to view and debug sencha touch code? Most of the apps don’t display properly in firefox.

    Thanks again!

    Regards,
    Mike

  8. Sameer Memon says

    I don’t want to display login form again and again. Instead it display login form only once. If user successfully logged in, server will send uniquely generated app key and for the next time when user open the app all the transaction takes place using that uniquely generated app key.

    • says

      You can save the key sent by the server, or a hash of the key to a cookie. When the application launches, read the cookie. If it’s present, consider the user authenticated and call the appropriate controller action.

      • Sameer Memon says

        Thanks for your response Jorqe.
        I am totally agree with you, but I have doubt like if someone clear the cookie then that key will also removed. And this time again we need to display login form.
        I want to display login form only once and will keep the app key forever.

        Can we use json writer, means will get app key from server and will write that key into json file.
        Every time user launch application, app will check the json file for the key, if key found ,app will pick the key and make the transaction using that key.

        For very first user it won’t get that app key and this time it will display register form to the user and once user enter his details will follow the same steps as discussed.
        But my problem is , I am unable to write app key into the json file.

        • Armin says

          First of all thank a lot for this tut Jorge.

          I’m implementing something simular like Sameer wants to do. My login form has an auto login checkbox. When its checked I skip the login form and show the main view.

          So what is the best solution to store the login information? One option is to store them in local storage but its nor really secure to store a password as plaintext in ls. Any hints on that? Thx

          • says

            Don’t store the password on the client at all. Not even encrypted. Upon first login, create a session id for the user on the server, send it to the client, and store it in a cookie. Set the expiration on the server and on the client to whatever period you want to autologin to be valid for. Next time the user comes to the site, read the session id from the cookie, and send it to the server where you will check if it maps to a session that has not expired. If it does, let the user in. If it doesn’t, ask the user to enter their credentials and start the process again.

  9. MudLuscious says

    Thanks for the amazing tutorial!
    I have everything working except a scoping issue when using “me” to call the functions in the controller after the initial AJAX call.
    me.signInFailure(‘Login failed. Please try again later.’);
    gives me an Uncaught Error: Object [object Object] has no method ‘signInFailure’.

    Even though the reference works in the section above that alerts the label when a user submits empty strings.

    Any suggestions? Thanks!
    -D

    • says

      I just realized that I had “singInFailure” instead of “signInFailure”. Might not have to do with your problem, but check to confirm.

      • MudLuscious says

        Yes, that’s the first thing I caught and was hoping was the case. Unfortunately, I still have scope issues when using “me” anywhere inside of the AJAX success or failure callbacks.

        i.e.
        me.signInFailure(loginResponse.message);
        will always return:
        Uncaught TypeError: Object [object Object] has no method ‘signInFailure”

        obviously some sort of scope issue..but can’t pin it down.

        • MudLuscious says

          I figured it out. Those method calls were wrapped in the ajax request. Silly brackets.
          Thanks again for the awesome info!

  10. Roland says

    Hi, thx for the tutorial.
    I still have a question:
    First I do the login, get the sessionToken including a UserID.
    On all following lists, views, panels… I only want to get data for the actual UserID.
    In the store I used the proxy: type ajax, with api attributes create, update….
    All works fine, but, how to pass the UserID to the proxy, after a successful login?
    Up to now I do not have any idea ;-(

    • Roland says

      OK, find a solution:
      took the UserID from the sessionToken and put it into a cookie after the successful login.
      This cookie then I can also use in my php files for doing something.
      Cheers Roland

    • says

      If you are using data stores, the load method of a store accepts a params object that you can use to send the UserID. If you are using the Ajax.request method, the same applies.

      • Roland says

        Hi Jorge, thx for your reply.
        I tried the extraParams, which works fine.
        One more question:
        do you know, if there is a function to get the extraParams?
        setExtraParam -> OK, but no ‘getExtraParam’ ???
        Couldn’t find one in the documentation.
        Cheers Roland

        • says

          I don’t think there is one. It’s not needed. If you mean that you need to extract information from the server’s response, you should be able to parse the json-formatted response into an object instance. The properties of this instance would contain the parameters sent by the server.

  11. Omar says

    I am building a social web app. It will require php and mysql data backend work to store userIDs along with other tables to store the user data. I was also considering using a backend framework (CodeIgnighter).

    Would you recommend handling all of the sign-in and session stuff solely through the sencha sign-in logic? Or should I just validate everything through PHP (or codeignighter framework)? Or should I be implementing a combination of both?

    If it matters I also want to be able to integrate with phone gap, to get my web app to the app store of multiple devices. I am looking for the simplest solution. If I could do everything through sencha framework, that would be great.

    • says

      Hey Omar. If you are using Sencha Touch for your app, I would recommend that you handle the client-side sign-in logic with ST. However, you need to validate everything on the server through PHP. So, it’s a combination. You will be able to use Phonegap without problems following with this approach.

  12. sinda says

    Hy,Thanks for this solution.I used it.
    But I have 2 problems:
    1- when I click in LogIn button,the username and the login are well sent to the database but the MainMenu view is not shown.
    2- If I enter the same login and username twice or more there are no bug which is impossible to have 2 users for example with the same login ?
    Any Help Please??

  13. Bharath says

    s Jorge. i saw that codes… thats code are related to our login page or i need to modify..

    login.ashx and logoff.ashx not working for me jorge.. and also i need more explanation about service part…

  14. Bharath says

    Uncaught Error: You’re trying to decode an invalid JSON String: public class Login : IHttpHandler
    {
    public void ProcessRequest(HttpContext context)
    {

    string result = �{\�success\�:\�false\�,\�message\�:\�Login failed. Please enter the correct credentials.\�}�;
    string username = context.Request.Form["user"];
    string password = context.Request.Form["pwd"];

    if (// Place your authentication logic here)
    {
    var sessionToken = // Create a session token here;
    result = �{\�success\�:\�true\�,\�message\�:\�\�,sessionToken:� + sessionToken.ToString() + �}�;
    }

    context.Response.ContentType = �application/json�;
    context.Response.Write(result);
    }

    public bool IsReusable
    {
    get
    {
    return false;
    }
    }
    }

    i got error like this.

  15. Joel says

    Hi Jorge, Great Tutorial.
    I am Joel and new to Sencha Touch and development in general.

    I managed to set up the login but after some CrossDomain issues using Ext.Ajax.request found out that I needed to the Ext.data.JsonP.request and most importantly GET method.

    I got an issue when i try to log in to a aspx site. The code sends the request to the site but the code does not enters in the succes: function (response).

    Automatically, when I click the Log in button the Google Chrome javascript console returns to me: Resource interpreted as Script but transferred with MIME type text/html: “https://Site.aspx?e=123&p=133&callback=Ext.data.JsonP.callback1&_dc=1365705476280″.

    Then I get a Uncaught SyntaxError: Unexpected token : from the aspx Site though the site responds with the correct (expected) json values. Is there a way you can help me here?

    And can you explain to me how the success: function (response) works?

    Thanks

  16. Scenery says

    i have a problem about when run here( var task = Ext.create(‘Ext.util.DelayedTask’, function() {} ) , error happen Uncaught TypeError: Cannot call method ‘apply’ of undefined

    • says

      Do you have the requires config in your form Login form panel? Like this: requires: ['Ext.form.FieldSet', 'Ext.form.Password', 'Ext.Label', 'Ext.Img', 'Ext.util.DelayedTask']

  17. says

    This was a fantastic tutorial. I’m going to use this as a proof of concept for logging into our system.

    The one thing I wish was in the tutorial was the ability to login with the GO button on iOS or Enter key on the keyboard.
    Fortunately since the documentation for sencha is really good this was simple to add.
    I added an itemId to the field set then added this code to the listeners section:

    {
    delegate: ‘#loginForm’,
    event: ‘action’,
    fn: ‘onLoginButtonTap’
    }

  18. says

    Thanks for the amazing tutorial!, you are just awesome sir, am just started learnign sencha without any JS background. but this tutorial really helped me to understand the basics.. really helped me alot …thank you sir, thank you very much

  19. sudhirkd says

    George, nice tutorial. Now a days, trend is to use RESTful calls to server where user-password is sent every request rather than creating session id. That helps in scaling server side and using the server as a service as well (i am server side developer).

    It would be great to see your approach to accomplish login mechanism in RestFul calls.

    Thanks,
    Sudhir

  20. Fred says

    Hi

    I copied all the codes, and i got the –> Uncaught TypeError: Object # has no method ‘getRouter’

    I’m sure i didn’t modify any part of the codes on this tutorial.. and i see that the others didn’t have this type of problem. I’m using Sencha Touch 2.2.0, if that matters for this case.

    I tried adding the routes : {<>}, but still didn’t solve the problem.

  21. firas says

    would this work with word press account ??
    I tried it on my word press account but couldn’t login

  22. GG says

    hey can you please tell me how to remember username and password…. I have used your login example to write login view and controller and passed my domain url … and it is working fine …but my client want an option to remember username and password option so can you please tell me how to add that option and how that works in the controller… Thank you

    • says

      You can save a “remember me” value to a cookie or local storage upon successful logon. In the application’s launch function, you can read this value. If present, you do not show the login view.

  23. Sur says

    HI,
    Thanks for the help. Now i am having problem parsing token my json is
    {“data”:{“token”:”50a3136d949cebb71e421d6e6d5abf21a44b123c”},”status”:”TRUE”,”message”:”successful”,”response_status”:200}
    how can i parse this.

  24. felipe says

    First I offer my apologies for the level of English :/
    Thanks Jorge, a great tutorial, achieved no problem connecting to php, and because the book is worth having and paying for tks.

    Saludos desde Colombia!!!

  25. Ricardo Honorato says

    Hello! Great tutorial!
    How can I propagate session storage in text field?
    can you help me?

    Thanks!!!

      • Ricardo says

        Hello Jorge! Thanks for answering.
        After logging in, assigns a value to one sessionStorage (sessionStorage.idloja = loginResponse.idloja), and would like to use it throughout the project (in a text field). Similar to session used in php. Is it possible?

        Thank you!

    • says

      Check that your views array in the application definition contains the MainMenu view:

      Ext.application({
      name: ‘Sample’,
      views: ['Login','MainMenu'],
      controllers:['Login'],
      launch: function () {

      Ext.Viewport.add([
      { xtype: 'loginview' },
      { xtype: 'mainmenuview' }
      ]);
      }
      });

  26. Nabarag says

    hey jorge… thax for the tute…. it helped me a lot… but 1 question… from where i get the url of login.ashx and logoff. ashx… plz help….

  27. Nabarag says

    And one more thing… if i am not persing the json and not using the login.ashx and logoff ashx part… while running the code i am getting an error
    Uncaught Error: [Ext.createByAlias] Cannot create an instance of unrecognized alias: widget.Main

    what should i do?? :( what i am missing?? actually what is the function of alias: widget.mainview?? plz help.. thanx a ton in advance :)

  28. says

    Jorge – Thanks so much for this tutorial! It has helped tremendously! I was wondering if you could share some code on how to check if the user is truly logged in upon app launch? I got everything working (per your tutorial), but am wanting to take my app to the *next* level and check to make sure the user is actually logged in and show them the menu bar instead of showing them the login screen every time.

  29. Mike says

    Hi, Excellent tutorial , thanks a lot for that!!

    i’m new to programming , can you please give me a sample file where i could replace the one you have ( url: ‘../../services/login.ashx’,) and see what happens when the log in is successful ?

    Thanks a lot!

  30. Ntenis says

    Hi, well done, nice tutorial keep it up.Can you tell me please how i can verify the username and password ,which are storesin mysql ?

    Cheers

  31. Sasha says

    Hi. Thank you for tutorial. Maybe somebody know how insert token in “Store object”.
    This method doesn’t look ok for me
    var store = Ext.getStore(“StoreName”);
    store.load({ params:{“token”:localStorage.getItem(“myToken”)}});
    Because I want use this store in different place of application (for example “pull down event”) – and for this situation I need call store.load({ params:{“token”:localStorage.getItem(“myToken”)}}); again

  32. Sasha says

    Also maybe somebody know how reset all view and store when I click log out? Because when I use other log and pass old data appears again.

  33. says

    The final code of Login.js Controller was not working to me because of the way it is arranged. I had to move the “signInFailure” and “signInSuccess” above the “onSignInCommand”! Do you happen to know why this happens?

  34. Sanjay says

    I have upgraded my secha application(2.2) to 2.3.1 framework.
    But after compiling the application and deploying on the Android device when i click on the application icon i am taken to the home page of the application but all i get to see is a blank screen. On the click of the app icon there is call which goes to APP47 for downloading the assets.

    Please help

  35. Fawaz Babu says

    Can u explain me how to make the user logged in until he presses log out. Now its asking for every time when i runs the app. Please help me.

    • says

      Save a session token to a cookie. Next time a user runs the app, read the cookie and if the session is still valid, active the main menu view instead of the login view. When the user logs out, destroy the cookie that contains the session token.

  36. Bhaskar says

    Thanks for tutorial , i need help in resolving this issue “Getting XMLHttpRequest cannot load file: data.json.Origin null is not allowed by Access-Control-Allow-Origin” , i have tried this “C:\Users\YOUR_USER\AppData\Local\Google\Chrome\Application\chrome.exe –allow-file-access-from-files –disable-web-security” to allow access but still the issue , what might be the problem, thanks in advance.

Leave a Comment

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