Question

I am developing a Sencha Touch 2 app with user authentication.

I use a token for authentication.

The logic.

Check is a token exists in local storage:

var tokenStore = Ext.getStore('TokenStore'),
token = tokenStore.getAt(0).get('token');

If there is a token, check if it's valid. I am doing a read from a model which is connected to my API which, returns success or fail - depending on the token - if it's valid or not.

 TestApp.model.CheckAuthModel.load(1, {
                scope: this,
                success: function(record) {
                  // Here, I know the token is valid

                },
                failure: function() {
                    console.log('failure');
                },
                callback: function(record) {
                    console.log('callback');
                    console.log();
                }
           });

And here is the router, which handles the logic for the views:

Ext.define("TestApp.controller.Router", {

    extend: "Ext.app.Controller",

    config: {

        refs: {
            HomeView: 'HomeView',
            LoginView: 'LoginView',
            ProductsView: 'ProductsView',
            ProductsViewTwo: 'ProductsViewTwo'
        },

        routes: {
            '': 'home',
            'home' : 'home',
            'login' : 'login',
            'products' : 'products',
            'testingtwo' : 'testingtwo'
        }
    },

    home: function () {

        console.log('TestApp.controller.Router home function');

        var initialItem = Ext.Viewport.getActiveItem(),
            comp = this.getHomeView();

        if (comp === undefined) comp = Ext.create('TestApp.view.HomeView');

        Ext.Viewport.animateActiveItem(comp, {
            type: 'slide',
            listeners: {
                animationend: function() { 
                   initialItem.destroy();
                }
            }
        });
    },

    login: function () {

        var initialItem = Ext.Viewport.getActiveItem(),
            comp = this.getLoginView();

        if (comp === undefined) comp = Ext.create('TestApp.view.LoginView');

        Ext.Viewport.animateActiveItem(comp, {
            type: 'slide',
            listeners: {
                animationend: function() { 
                   initialItem.destroy();
                }
            }
        });
    },

    products: function () {

        var initialItem = Ext.Viewport.getActiveItem(),
            comp = this.getProductsView();

        if (comp === undefined) comp = Ext.create('TestApp.view.ProductsView');

        Ext.Viewport.animateActiveItem(comp, {
            type: 'slide',
            listeners: {
                animationend: function(){
                    initialItem.destroy();
                }
            }
        });
    },

    testingtwo: function () {

        var initialItem = Ext.Viewport.getActiveItem(),
            comp = this.getProductsViewTwo();

        if (comp === undefined) comp = Ext.create('TestApp.view.ProductsViewTwo');

        Ext.Viewport.animateActiveItem(comp, {
            type: 'slide',
            listeners: {
                animationend: function(){
                    initialItem.destroy();
                }
            }
        });
    },

    launch: function() {

        console.log('TestApp.controller.Router launch!');
    }
});

Now, how can I link the router with the check auth model callback?

I want to know the auth state when the app reaches the router.

In other MVC frameworks, I could do a before filter, on the router, check for auth and handle the routes accordingly.

Can i do this in Sencha Touch 2?

Any ideas?

Was it helpful?

Solution

Hi I think this section in the documentation is exactly what you need:

before : Object
Provides a mapping of Controller functions to filter functions that are run before them when dispatched to from a route. These are usually used to run pre-processing functions like authentication before a certain function is executed. They are only called when dispatching from a route. Example usage:

Ext.define('MyApp.controller.Products', {
    config: {
        before: {
            editProduct: 'authenticate'
        },

        routes: {
            'product/edit/:id': 'editProduct'
        }
    },

    //this is not directly because our before filter is called first
    editProduct: function() {
        //... performs the product editing logic
    },

    //this is run before editProduct
    authenticate: function(action) {
        MyApp.authenticate({
            success: function() {
                action.resume();
            },
            failure: function() {
                Ext.Msg.alert('Not Logged In', "You can't do that, you're not logged in");
            }
        });
    }
});

http://docs.sencha.com/touch/2.3.1/#!/api/Ext.app.Controller-cfg-before

Of course, it's still up to you to decide whether you should check every time or should cache the auth result for sometime.

Updated to answer comment below Honestly, i am not sure how they was going to declare that static method Authenticate in Sencha (you would be able to do it normally through Javascript i think, i.e.: prototype).

But there are other better options to solve just that Authenticate function:

  • Just create a singleton class that handle utility stuffs. http://docs.sencha.com/touch/2.3.1/#!/api/Ext.Class-cfg-singleton
  • If you really want to use MyApp, you can declare within the Ext.app.Application (in app.js). Then call it from the global instance MyApp.app.some_function(). I wouldn't exactly recommend this method because you change app.js, that might bring problem if you upgrade sencha touch.

OTHER TIPS

You could implemented auth check in application's launch function or in your auth controller's init function and based on the response redirect the to appropriate url. Something like this:

  TestApp.model.CheckAuthModel.load(1, {
            scope: this,
            success: function(record) {
               this.redirectTo("home/");

            },
            failure: function() {
                this.redirectTo("login/");
                console.log('failure');
            },
            callback: function(record) {
                console.log('callback');
                console.log();
            }
       });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top