sqlite - 仅在 sencha 的 native 应用程序中第一次登录屏幕

标签 sqlite cordova extjs authentication sencha-touch

我正在开发sencha touch 中的 native 应用程序。我想创建一个登录 View ,该 View 仅在第一次时可见。任何建议如何解决它。

激活.js

Ext.define('FOS.view.Activation', {
    extend: 'Ext.form.Panel',
    alias: "widget.activationview",
    requires: ['Ext.form.FieldSet', 'Ext.form.Password', 'Ext.Label', 'Ext.Img', 'Ext.util.DelayedTask'],
    config: {
        title: 'Login',
        items: [

            {
                xtype: 'label',
                html: 'Activation failed. Please enter the correct credentials.',
                itemId: 'activationFailedLabel',
                hidden: true,
                hideAnimation: 'fadeOut',
                showAnimation: 'fadeIn',
                style: 'color:#990000;margin:5px 0px;'
            },
            {
                xtype: 'fieldset',
                title: ' ',
                items: [
                    {
                        xtype: 'textfield',
                        placeHolder: 'Enter Agency Id',
                        itemId: 'agencyIdTextField',
                        name: 'agencyIdTextField',
            label: 'Agency Id',
                        labelWidth: '40%',
                        //required: true
                    },
                    {
                        xtype: 'textfield',
                        placeHolder: 'Enter App Id',
                        itemId: 'appIdTextField',
                        name: 'appIdTextField',
            label: 'App Id',
                        labelWidth: '40%',
                       // required: true
                    }
                ]
            },
            {
                xtype: 'button',
                itemId: 'activationButton',
                ui: 'action',
                padding: '10px',
                text: 'Activate'
            }
         ],
        listeners: [{
            delegate: '#activationButton',
            event: 'tap',
            fn: 'onActivationButtonTap'
        }]
    },
    onActivationButtonTap: function () {

        var me = this,
            agencyidField = me.down('#agencyIdTextField'),
            appidField = me.down('#appIdTextField'),
            label = me.down('#activationFailedLabel'),
            agencyid = agencyidField.getValue(),
            appid = appidField.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('activationCommand', me, agencyid, appid);

            agencyidField.setValue('');
            appidField.setValue('');
        });

        task.delay(500);

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

登录.js

Ext.define('FOS.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: '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: ' ',
                items: [
                    {
                        xtype: 'textfield',
                        placeHolder: 'Enter UserName',
                        itemId: 'userNameTextField',
                        name: 'userNameTextField',
            label: 'UserName',
                        labelWidth: '40%',
                        //required: true
                    },
                    {
                        xtype: 'passwordfield',
                        placeHolder: 'Enter Password',
                        itemId: 'passwordTextField',
                        name: 'passwordTextField',
            label: 'Password',
                        labelWidth: '40%',
                       // 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();
    }
});

MainMenu.js

Ext.define('FOS.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

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

   config: {
        refs: {
            loginView: 'loginview',
            mainMenuView: 'mainmenuview',
        activationView: 'activationview'
        },
        control: {
        activationView: {
                activationCommand: 'onActivationCommand'
            },
               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' };
    },

onActivationCommand: function (view, agencyid, appid) {

        console.log('AgencyId: ' + agencyid + '\n' + 'AppId: ' + appid);

        var me = this,
            activationView = me.getActivationView();

        if (agencyid.length === 0 || appid.length === 0) {

            activationView.showActivationFailedMessage('Please enter your Agency Id and App Id.');
            return;
        }

        activationView.setMasked({
            xtype: 'loadmask',
            message: 'Activating...'
        });

            me.activationSuccess();     //Just simulating success.

    },

    activationSuccess: function () {
        console.log('Activated.');
        var activationView = this.getActivationView();
        loginView = this.getLoginView();
        activationView.setMasked(false);

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

    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 User Name 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.singInFailure(loginResponse.message);
                }
            },
            failure: function (response) {
                me.sessionToken = null;
                me.singInFailure('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());
    }
});

app.js

//<debug>
Ext.Loader.setPath({
    'Ext': 'touch/src',
    'FOS': 'app'
});
//</debug>

Ext.application({
    controllers: ["Login"],

    name: 'FOS',

    requires: [
        'Ext.MessageBox'
    ],

    views: ['Activation','Login','MainMenu'],



    icon: {
        '57': 'resources/icons/Icon.png',
        '72': 'resources/icons/Icon~ipad.png',
        '114': 'resources/icons/Icon@2x.png',
        '144': 'resources/icons/Icon~ipad@2x.png'
    },

    isIconPrecomposed: true,

    startupImage: {
        '320x460': 'resources/startup/320x460.jpg',
        '640x920': 'resources/startup/640x920.png',
        '768x1004': 'resources/startup/768x1004.png',
        '748x1024': 'resources/startup/748x1024.png',
        '1536x2008': 'resources/startup/1536x2008.png',
        '1496x2048': 'resources/startup/1496x2048.png'
    },

    launch: function() {
        // Destroy the #appLoadingIndicator element
        Ext.fly('appLoadingIndicator').destroy();

        // Initialize the main view

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

    onUpdated: function() {
        Ext.Msg.confirm(
            "Application Update",
            "This application has just successfully been updated to the latest version. Reload now?",
            function(buttonId) {
                if (buttonId === 'yes') {
                    window.location.reload();
                }
            }
        );
    }
});

我只需要一次此激活 View 。 网络服务尚不可用......

最佳答案

基本上,您所寻找的功能类似于大多数网站和 native 应用程序上提供的记住我SSO(单点登录)功能。我自己最近在我的一个应用程序中需要这个。

通过 sencha,您可以使用 HTML5 存储。用户成功登录后,将某些用户详细信息(例如登录状态、访问 token 、用户 ID 等)存储到 HTML5 数据库中。您可以轻松地在其中存储最多 5MB 的数据,并且由于 sencha 在 webkit 等现代 Web 浏览器上运行,因此您可以使用该 api 并用它做一些事情。

到目前为止,我已经在我的应用程序中创建了一个包含各种字段(例如用户 ID、登录状态和访问 token )的模型。例如,您可以拥有类似的模型 -

Ext.define('MyApp.model.Userinfo',{
    extend:'Ext.data.Model',
    config:{
        identifier: 'uuid',
        store:'MyApp.store.Userinfo',
        fields:[                 
           {name: 'id', type: 'string' },
           {name: 'userid', type: 'string' },
           {name:'login_status',type:'string'},
           {name:'access_token',type:'string'}
        ]    
    }        
});

您可以根据您的要求添加字段数量,并为每个字段选择合适的类型。但你的模型应该有一个唯一的标识符。使用 ST2.0,您可以使用 identifier:'uuid' 为您的存储分配唯一标识符。

然后是商店,它可以像 -

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

最后,登录成功后,您可以使用 -

将数据添加到本地存储中
  var userInfoData=Ext.getStore('Userinfo');                                
  userInfoData.removeAll();
  userInfoData.getProxy().clear();
  userInfoData.add({userid:'user_id_to_store',login_status:"true",access_token:'generated_access_token'});
  userInfoData.sync();

最后,在您的 app.js 中,检查此本地存储中的条目并验证访问 token 的可靠性。所以在 launch 方法中,

var userInfoData=Ext.getStore('Userinfo');              
if(null!=userInfoData.getAt(0)){
    var status = userInfoData.getAt(0).get('login_status');
    var user_id=userInfoData.getAt(0).get('userid');
    var access_token = userInfoData.getAt(0).get('access_token');   

    //validate access token, check user id and status and load your next view that comes after login    

}else{
    // if reached here, that means user is not logged in.
    // load your login view.  
}

我无法阅读您的整个代码并对其进行编辑。但这是我所使用的,到目前为止它的工作没有任何问题。您可以根据您的应用程序和要求轻松更改它。

<小时/>

注意

该代码已经存在一年多了。所以它可能不适用于最新的 ST 版本(未经测试)。 但想法是一样的。干杯。 :)

关于sqlite - 仅在 sencha 的 native 应用程序中第一次登录屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14642944/

相关文章:

css - 在 meteor cordova 应用程序中全局禁用 iOS 9 上的放大镜

javascript - 在每个 AJAX 请求中发送用户详细信息( session token )(Sencha Touch 2)

javascript - 多级行扩展网格

c++ - 在循环中使用 sqlite3_bind_XXX

caching - 如何在PhoneGap中缓存图像和html文件

java - SQLite group_concat 下一行

jquery - Cordova iOS onResume 在启动时触发并导致应用程序崩溃

javascript - ExtJS:使拖动/平移无需缩放即可工作

java - 我的测验应用程序中的 SQLite 语句 ON DELETE CASCADE 语句出现错误

sqlite - 附加数据库中的外部内容FTS4表