授权服务在angularjs中的页面刷新时失败

时间:2014-02-28 13:19:02

标签: angularjs

使用POST实施授权 问题是当我进入特权页面时说“/ admin”它可以工作,但是当我刷新页面时 手动,管理页面重定向到'/ unauthorized'页面

权限服务

angular.module('myApp')
    .factory('PermissionsService', function ($rootScope,$http,CookieService) {
        var permissionList;
        return {
            setPermissions: function(permissions) {
                permissionList = permissions;
                $rootScope.$broadcast('permissionsChanged')
            },
            getPermissions: function() {
                var roleId = 5
                if(CookieService.getLoginStatus())
                    var roleId = CookieService.getUserData().ROLE_ID;

                return $http.post('api/user-permissions', roleId).then(function(result){
                    return result.data;
                });
            },
            hasPermission: function (permission) {
                permission = permission.trim();
                return _.some(permissionList, function(item) {
                    if(_.isString(item.name))
                        return item.name.trim() === permission
                });
            }
        };
    });

hasPermissions指令

angular.module('myApp')
    .directive('hasPermission', function(PermissionsService) {
        return {
            link: function(scope, element, attrs) {
                if(!_.isString(attrs.hasPermission))
                    throw "hasPermission value must be a string";

                var value = attrs.hasPermission.trim();
                var notPermissionFlag = value[0] === '!';
                if(notPermissionFlag) {
                    value = value.slice(1).trim();
                }

                function toggleVisibilityBasedOnPermission() {
                    var hasPermission = PermissionsService.hasPermission(value);

                    if(hasPermission && !notPermissionFlag || !hasPermission && notPermissionFlag)
                        element.show();
                    else
                        element.hide();
                }
                toggleVisibilityBasedOnPermission();
                scope.$on('permissionsChanged', toggleVisibilityBasedOnPermission);
            }
        };
    });

app.js

var myApp = angular.module('myApp',['ngRoute','ngCookies']);

myApp.config(function ($routeProvider,$httpProvider) {
    $routeProvider
        .when('/', {
            templateUrl: 'app/module/public/index.html',
            header: 'app/partials/header.html',
            footer: 'app/partials/footer.html'
        })
        .when('/login', {
            templateUrl: 'app/module/login/login.html',
            header: 'app/partials/header.html',
            footer: 'app/partials/footer.html'
        })
        .when('/home', {
            templateUrl: 'app/module/home/home.html',
            header: 'app/partials/header.html',
            footer: 'app/partials/footer.html'
        })
        .when('/register', {
            templateUrl: 'app/module/register/register.html',
            header: 'app/partials/header.html',
            footer: 'app/partials/footer.html'
        })
        .when('/admin', {
            templateUrl: 'app/module/admin/admin.html',
            header: 'app/partials/header.html',
            footer: 'app/partials/footer.html',
            permission: 'admin'
        })
        .when('/unauthorized', {
            templateUrl: 'app/partials/unauthorized.html',
            header: 'app/partials/header.html',
            footer: 'app/partials/footer.html'
        })
        .otherwise({redirectTo: '/'});

    $httpProvider.responseInterceptors.push('securityInterceptor');
});

myApp.provider('securityInterceptor', function() {
    this.$get = function($location, $q) {
        return function(promise) {
            return promise.then(null, function(response) {
                if(response.status === 403 || response.status === 401) {
                    $location.path('/unauthorized');
                }
                return $q.reject(response);
            });
        };
    };
});

myApp.run(function($rootScope, $location, $window, $route, $cookieStore, CookieService, PermissionsService) {
    PermissionsService.getPermissions().then(function(permissionList){
        PermissionsService.setPermissions(permissionList);
    });

    // Check login status on route change start
    $rootScope.$on( "$routeChangeStart", function(event, next, current) {
        if(!CookieService.getLoginStatus() && $location.path() != '/register' && $location.path() != '/login') {
            $location.path("/");
            $rootScope.$broadcast('notloggedin');
        }

        if(CookieService.getLoginStatus() && $location.path() == '/login') {
            $location.path("/home");
        }

        var permission = next.$$route.permission;
        if(_.isString(permission) && !PermissionsService.hasPermission(permission))
            $location.path('/unauthorized');

    });

    // Adds Header and Footer on route change success
    $rootScope.$on('$routeChangeSuccess', function (ev, current, prev) {
        $rootScope.flexyLayout = function(partialName) { return current.$$route[partialName] };
    });
});

CookieService

angular.module('myApp')
    .factory('CookieService', function ($rootScope,$http,$cookieStore) {
        var cookie = {
            data: {
                login: false,
                user: undefined
            },
            saveLoginData: function(user) {
                cookie.data.login = true;
                cookie.data.user = user;
                $cookieStore.put('__iQngcon',cookie.data);
            },
            deleteLoginData: function() {
                cookie.data.login = false;
                 cookie.data.user = undefined;
                 $cookieStore.put('__iQngcon',cookie.data);
            },
            getLoginStatus: function() {
                if($cookieStore.get('__iQngcon') === undefined)
                    return cookie.data.login;

                return $cookieStore.get('__iQngcon').login;
            },
            getUserData: function() {
                return $cookieStore.get('__iQngcon').user;
            }
        };

        return cookie;
    });

似乎页面刷新时权限数据丢失了。有没有其他方法可以解决问题?或者代码有问题吗?

2 个答案:

答案 0 :(得分:3)

  

当我手动刷新页面时,管理页面将重定向到   '/ unauthorized'页面

这不是预期的行为吗?如果您重新加载页面;然后所有UI状态都丢失了;这就像关闭应用程序并从头开始。

  

似乎页面刷新时权限数据丢失了。在那儿   我可以用任何其他方式解决问题吗?或者有任何问题   代码??

如果您希望能够在页面重新加载后保留UI状态,则必须以某种方式保留登录信息,例如在浏览器cookie中。当应用加载时;检查该cookie值。如果存在,您可以从数据库加载用户信息,实际上是镜像登录。

我会谨慎地将实际用户凭据存储在没有某种加密类型的cookie中。 我使用的一种方法是存储唯一的用户密钥,可以将其发送到DB以加载用户信息。有时这可能是与用户关联的UUID,避免使用自动递增主键,因为这很容易更改以访问其他用户的帐户。

答案 1 :(得分:0)

不得不思考一段时间并做出以下改变才能发挥作用。这可能不是最好的做法,但你为我工作。如果有人建议我在评论中找到更好的解决方案,我将不胜感激。

myApp.run(function($rootScope, $location, $window, $route, $cookieStore, CookieService, PermissionsService) {
    var permChanged = false;

    PermissionsService.getPermissions().then(function(permissionList){
        PermissionsService.setPermissions(permissionList);
    });

    // Check login status on route change start
    $rootScope.$on( "$routeChangeStart", function(event, next, current) {
        console.log('$routeChangeStart');
        if(!CookieService.getLoginStatus() && $location.path() != '/register' && $location.path() != '/login') {
            $location.path("/");
            $rootScope.$broadcast('notloggedin');
        }

        if(CookieService.getLoginStatus() && $location.path() == '/login') {
            $location.path("/home");
        }

        $rootScope.$on('permissionsChanged', function (ev, current, prev) {
            permChanged = true;
        });

        if(CookieService.getLoginStatus() && permChanged) {
            var permission = next.$$route.permission;
            if(_.isString(permission) && !PermissionsService.hasPermission(permission))
                $location.path('/unauthorized');
        }

    });

    // Adds Header and Footer on route change success
    $rootScope.$on('$routeChangeSuccess', function (ev, current, prev) {
        $rootScope.flexyLayout = function(partialName) { return current.$$route[partialName] };
    });
});

我所做的是等待设置权限,然后使用 permissionChanged 广播将 permChanged 变量设置为true,然后结合if user loginin status和如果有

,则 permchanged 必须检查权限
$rootScope.$on('permissionsChanged', function (ev, current, prev) {
                permChanged = true;
            });

            if(CookieService.getLoginStatus() && permChanged) {
                var permission = next.$$route.permission;
                if(_.isString(permission) && !PermissionsService.hasPermission(permission))
                    $location.path('/unauthorized');
            }