如果未通过异常身份验证,则 angularjs 重定向到登录页面 [英] angularjs redirect to login page if not authenticated with exceptions

查看:28
本文介绍了如果未通过异常身份验证,则 angularjs 重定向到登录页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

忘了提到我只使用 AngularJs 一个星期,所以如果你看到一些你认为应该改进并且与问题本身无关的东西,请随时在评论中告诉我部分.

forgot to mention that i've been working with AngularJs for a week only, so if you see something you think should be changed for the better and is not related to the question itself feel free to tell me on the comments section.

好的,所以我有我的身份验证控制器和提供程序,我不会显示它们,因为它们与问题的范围无关.然后我有一个拦截器来检查用户在调用时是否经过身份验证.如果是这样,我在请求中设置 Authentication 标头以包含用户的令牌,如果不是,我将用户重定向到登录页面,甚至不向服务器发出请求(显然,如果有人绕过这个存在也是 API 上的 Authorize).

ok, so I have my authentication Controllers and providers which I won't show because they're irrelevant for the scope of the question. Then I have an interceptor to check if the user is authenticated when a Call is made. If so I set the Authentication header on the request to include the user's Token if not I redirect the user to the login page and don't even make the request to the server (obviously if someone bypasses this theres also an Authorize on the API).

我想要添加一些例外,这意味着即使用户没有 Auth Token,我也希望允许一些页面.如果它是特定路径,我可以这样做,但我想允许访问我的 404 页面,并且它在我指定 .otherwiseRouting 中转到 404 页面,我怎样才能让我的拦截器只重定向到登录,如果它不去这个页面.

What I want is to add a few exceptions, meaning there are some pages I want to allow even if the user has no Auth Token. I'm able to this if it's a specific path, but I want to allow my 404 page to be accessed and it's in the Routing that I'm specifying .otherwise to go to the 404 page, how can I make so that my interceptor only redirects to login if it's not going to this page.

拦截器

.factory('authInterceptorService', ['$q', '$location', 'localStorageService', function ($q, $location, localStorageService) {

    var authInterceptorServiceFactory = {};

    var authData = localStorageService.get('authorizationData');

    var _request = function (config) {

        config.headers = config.headers || {};

        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        } else if ($location.path != '/accounts/login' && $location.path != '/accounts/register') {
            $location.path('/accounts/login');
        }

        return config;
    }

    var _responseError = function (rejection) {
        if (rejection.status === 401) {
            $location.path('/accounts/login');
        }
        return $q.reject(rejection);
    }

    authInterceptorServiceFactory.request = _request;
    authInterceptorServiceFactory.responseError = _responseError;

    return authInterceptorServiceFactory;
}])

在我的路由中

 $urlRouterProvider.otherwise('/page-not-found');

 $stateProvider
     (...)//rest of the states

     .state('page-not-found', {
         url: '/page-not-found',
         templateUrl: '/Content/partials/error/404.html',
         data: {
             displayName: false
         }
     })

     (...)//rest of the states

我尝试将 '/page-not-found' 添加到我的 if 但它不会按预期工作,因为在检查位置时第一次仍然没有重定向.

I tried to add '/page-not-found' to my if but it won't work as expected because by the time the location is checked for the first time it's still not redirected.

编辑正如 charlietfl 所建议的那样,我现在正在尝试使用 resolve,但它甚至没有通过我的函数.

edit As sugested by charlietfl I'm now trying to use resolve but it's not even passing my function.

我从拦截器中删除了这段代码:

I removed this code from my interceptor:

else if ($location.path != '/accounts/login' && $location.path != '/accounts/register') {
    $location.path('/accounts/login');
}

向认证模块添加一个新的service:

and add a new service to the authentication module:

.service('authCheckService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {
    var self = {
        'onlyLoggedIn': function ($state, $q) {
            var deferred = $q.defer();
            var authData = localStorageService.get('authorizationData');
            console.log(authData);
            if (authData) {
                deferred.resolve();
            } else {
                deferred.reject();
                $state.go('login');
            }
            return deferred.promise;
        }
    }

    return self;
}]);

我试图将其称为:

.state('smo-dashboard', {
        url: '/dashboard',
        templateUrl: '/Content/partials/dashboard.html',
        resolve: authCheckServiceProvider.onlyLoggedIn
})

请注意,我正在尝试记录 authData var 以检查它是否正常工作,但不是,控制台上也没有错误.

notice that i'm trying to log authData var to check if it's working but it isn't and there's no error on the console also.

推荐答案

终于想通了如何使用resolve解决.

Finally figured out how to solve it using resolve.

首先我完全删除了我之前使用的拦截器.然后我在我的路由 .config 中创建了一个函数,用于每个 resolve 进行身份验证.最后处理我的 resolve 我正在使用 $stateChangeError 重定向到登录 state

first of all I completely removed the interceptor I was using before. then I made a function inside my Routing .config to use with every resolve for the authentication. finally to handle my resolve I'm using $stateChangeError to redirect to the login state

路由配置

.config(function ($stateProvider, $urlRouterProvider) {

    // function to check the authentication //
    var Auth = ["$q", "authService", function ($q, authService) {
        authService.fillAuthData;
        if (authService.authentication.isAuth) {
            return $q.when(authService.authentication);
        } else {
            return $q.reject({ authenticated: false });
        }
    }];

    /* if the state does not exist */
    $urlRouterProvider
        .otherwise('/page-not-found'); 

    $stateProvider

        // state that allows non authenticated users //
        .state('home', {
            url: '/',
            templateUrl: '/Content/partials/home.html',
        })

        // state that needs authentication //
        .state('smo-dashboard', {
            url: '/dashboard',
            templateUrl: '/Content/partials/dashboard.html',
            resolve: {
                auth: Auth
            }
        })

        // errors //
         .state('page-not-found', {
             url: '/page-not-found',
             templateUrl: '/Content/partials/error/404.html'
         })

        // accounts //
        .state('login', {
            url: '/accounts/login',
            templateUrl: '/Content/partials/account/login.html'
        })

        // OTHER STATES //
    }
);

在主控制器中

$scope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {
    $state.go("login");
});

这篇关于如果未通过异常身份验证,则 angularjs 重定向到登录页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆