1

我需要以下功能:当用户进入登录表单时,浏览器应自动填写用户名和密码。

我的实现工作(在 FF 和 Chrome 上)但是,存在这个错误(不一致),在用户之间切换时模型数据没有正确更新。这意味着我使用用户 ONE 登录,然后注销,并输入用户 TWO 的凭据,但在单击登录按钮后,我仍然使用用户 ONE 登录。

登录表单如下所示:

<form class="form-horizontal" ng-submit="login(credentials)">
    <fieldset>
        <div class="form-group" ng-class="{'has-error' : validationErrors.email}">
            <div class="btn-icon-lined btn-icon-round btn-icon-sm btn-default-light">
                <span class="glyphicon glyphicon-envelope"></span>
            </div>
            <input type="email" name="email" autocomplete="on" ng-model="credentials.email" class="form-control input-lg input-round text-center" placeholder="Email" >
            <span class="help-block" ng-if="validationErrors.email">{{ validationErrors.email.0 }}</span>
        </div>
        <div class="form-group" ng-class="{'has-error' : validationErrors.password}">
            <div class="btn-icon-lined btn-icon-round btn-icon-sm btn-default-light">
                <span class="glyphicon glyphicon-lock"></span>
            </div>
            <input type="password" name="password" autocomplete="on" ng-model="credentials.password" class="form-control input-lg input-round text-center" placeholder="Password" >
            <span class="help-block" ng-if="validationErrors.password">{{ validationErrors.password.0 }}</span>
        </div>
        <div class="form-group">
            <input type="submit" value="Sign in" class="btn btn-primary btn-lg btn-round btn-block text-center">
        </div>
    </fieldset>
</form>

登录控制器包含以下内容:

// Login Controller
app.controller( 'LoginCtrl', ['$rootScope','$scope', '$state', 'AppUser', 'Auth',
    function($rootScope, $scope, $state, AppUser, Auth){

    console.log("LoginCtrl");

    $scope.credentials = {
        "email" : "",
        "password": ""
    };

    $scope.redirectAfterLogin = function() {
        // set user data
        AppUser.setUserData($scope.user);
        ...
    }

    // Login attempt handler
    $scope.login =  function(data) {
        data = {'user':data};

        Auth.login(data,
            function(response) {
                $scope.user = response.data;

                ...

            },function(response){
                $scope.validationErrors = {
                    "email" : [],
                    "password": []
                };
                ...
            }

        );
    };

}]);

登出:

// logout
$scope.logout  = function() {
    // remove attempted URL, if any
    AppUser.removeAttemptUrl();

    data =  {'user':
        {
            'email': $scope.user.email
        }
    };
    Auth.logout(data,
        function(){
            AppUser.unSetUserData($scope.user); // se method below
            $state.go(ApplicationState.LOGIN);
        },
        function(){
            console.log("Logout failed");
     });
}

angular.module('app.service').factory('AppUser', [
'$window', '$rootScope', 'LocalStorage', 'appConfig', '$injector', '$location',
function($window, $rootScope, localStorage, appConfig, $injector, $location){

// Redirect to the original requested page after login
var redirectToUrlAfterLogin = { url: '' };
var userKey = "AppUser";
var userData = {};

angular.element($window).on('storage', function(event) {
    if (event.key === userKey) {
        $rootScope.$apply();
    }
});

return {

    /**
     * Redirect to the original requested page after login
     * - we need to be able to save the intended URL, request it, remove it and redirect to it
     */
    saveAttemptUrl: function() {
        if ($location.path().toLowerCase() != ApplicationState.LOGIN) {
            redirectToUrlAfterLogin.url = $location.path();
        }
        else {
            redirectToUrlAfterLogin.url = '/';
        }
    },
    getAttemptedUrl: function() {
        return redirectToUrlAfterLogin.url;
    },
    removeAttemptUrl: function() {
        // re-initialize URL
        redirectToUrlAfterLogin = { url: '' };
    },
    redirectToAttemptedUrl: function() {
        $location.path(redirectToUrlAfterLogin.url);
    },

    /**
     * Returns the current user's state
     * @returns {boolean}
     */
    isAuthenticated: function() {
        userData = JSON.parse(localStorage.get(userKey) || '{}').userData;

        if (!this._isSessionExpired()) {
            if (userData !== undefined){
                return !!(userData.id !== null && userData.email);
            }
            else{
                return false;
            }
        }
        else{
            if (userData !== undefined){
                var data =  {
                    'user':{
                        'email': userData.email
                    }
                }

                // we use $injector to avoid Circular Dependency which is thrown by injecting the $api service
                $injector.invoke(['$api', function($api){
                    $api.auth.logout(data).success(function(result){
                        userData = {};
                        localStorage.remove(userKey);
                    });
                }]);
                return false;
            }
        }
    },

    getUserData: function() {
        return userData;
    },

    setUserData: function(data) {
        userData = data;
        localStorage.set(userKey, JSON.stringify({
            userData: data,
            stamp: Date.now()
        }));
    },

    unSetUserData: function() {
        userData = {};

        localStorage.remove(userKey);
    },

    _isSessionExpired: function() {
        var session = JSON.parse(localStorage.get(userKey) || '{}');
        return (Date.now() - (session.stamp || 0)) > appConfig.sessionTimeout;
    },

    userData : userData
};

}]);

关于为什么会发生这种情况的任何想法?

4

2 回答 2

1

注销后localStorage使用浏览器检查器检查。
可能你会发现一些你没有清除的变量。所以只需清除存储,它应该没问题。

要清除存储使用:

localStorage.clear();

$rootScope如果您没有刷新所有数据仍然存在,那么另一个问题可能是您没有清理。

于 2015-07-13T12:50:39.253 回答
0

这是问题吗?userKey您显示的代码中似乎没有定义。

// add userKey param
unSetUserData: function(userKey) {
    userData = {};

    localStorage.remove(userKey);
},
于 2015-07-13T12:46:38.877 回答