使用 $locationChangeStart 进行 angularjs 身份验证 [英] angularjs authentication using $locationChangeStart

查看:27
本文介绍了使用 $locationChangeStart 进行 angularjs 身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在验证下面给出的 Angular 应用程序代码,基本上我正在检查来自后端的令牌,如果令牌有效,则我们可以允许用户查看允许的页面.

它有点工作但问题是当我去/jobs页面有点加载然后重定向到登录页面但我不想最初显示工作页面几秒钟它应该快速重定向否则它不会加载工作页面.

在 app.js 中

 var app = angular.module('ttt', ['ui.router', 'ui.bootstrap', 'ngResource', "ngStorage", "ngProgress", "ngCookies", 'angular-jwt', 'ngLodash','tagged.directives.infiniteScroll']);app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', "$httpProvider", function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {$locationProvider.html5Mode(true);$urlRouterProvider.otherwise(function ($stateParams) {console.log("val check", $stateParams, window.location);window.location.href = "/undefined";});$stateProvider.state("工作", {网址:/工作",templateUrl: "views/dashboard.html",控制器:JobController 作为 JobCtrl",解决 : {formInfo : ["AuthService",function (AuthService) {返回 AuthService.getFormInfo();}]}}).state("未定义", {网址:/未定义",templateUrl: "views/pagenotfound.html",bodyClass:错误错误-404 错误为中心"}).state("登录", {网址:/登录",templateUrl: "views/login.html",控制器:LoginController 作为 LoginCtrl",解决 : {formInfo : ["AuthService",function (AuthService) {返回 AuthService.getFormInfo();}]}})}]);

app.run(['$rootScope', 'ngProgressFactory', '$state', '$compile', '$location', '$cookies', 'jwtHelper','AuthService', function ($rootScope, ngProgressFactory, $compile, $state, $location, $cookies, jwtHelper,AuthService) {$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {$rootScope.progressbar = ngProgressFactory.createInstance();$rootScope.progressbar.start();$rootScope.location = $location;});var authPreventer = $rootScope.$on('$locationChangeStart', function (event, toState, toParams, fromState, fromParams, options) {var notCheckRoute = ["/undefined", "/signin", "/login"];//event.preventDefault();if(notCheckRoute.indexOf($location.path()) !== -1){AuthService.checkPermission().then(函数(数据){//event.preventDefault();如果(数据.活动){$location.path('/home');}别的{$location.path('/登录');}});}别的{//event.preventDefault();AuthService.checkPermission().then(函数(数据){如果(!数据.活动){$location.path('/登录');}别的{//$location.path('/jobs');}});}});$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {$rootScope.progressbar.complete();$rootScope.bodyClass = toState.bodyClass;});$rootScope.$on('$stateChangeError', function (event) {//$state.go('undefined');});}]);

服务中

 app.service('AuthService',['jwtHelper','$cookies','$location','$window','$http','$q',function (jwtHelper,$cookies,$location,$window,$http,$q) {this.login = 函数(令牌){var payload = jwtHelper.decodeToken(token);};this.logout = 函数(数据){};var validatetoken = 未定义;this.checkPermission = 函数 () {如果(!验证令牌){//使用 $q 创建延迟对象var deferred = $q.defer();//获取validatetoken表单后端$http.post('/api/validatetoken', {token: $cookies.get('token')}).then(函数(结果){//将获取的validatetoken保存到局部变量验证令牌 = result.data;//解决延迟deferred.resolve(validatetoken);}, 函数(错误){验证令牌 = 错误;deferred.reject(error);});//将validatetoken 对象设置为promise 直到结果返回验证令牌 = deferred.promise;}返回 $q.when(validatetoken);}this.getFormInfo = 函数 () {返回 $http.get("/api/getloginurl");}}]);

解决方案

我不想在最初几秒钟内显示工作页面,它应该快速重定向,否则不会加载工作页面.

使用 ui-router 时,避免将代码放入 $locationChangeStart.这会导致与 ui-router 操作发生冲突.

要防止加载作业页面,请检查解析器中的授权状态.

$stateProvider.state("jobs", {网址:/工作",templateUrl: "views/dashboard.html",控制器:JobController 作为 JobCtrl",解决 : {formInfo : ["AuthService",function (AuthService) {返回 AuthService.getFormInfo();}],//检查权限权限:[AuthService",功能(AuthService){返回 AuthService.checkPermission().then(函数(数据){如果(!数据.活动){返回数据} 别的 {//如果未授权则拒绝抛出未授权";};}).catch(函数(错误){console.log("错误");抛出错误;});}];}})

通过拒绝解析,状态更改将被中止并且页面不会加载.

<小时>

更新

<块引用>

我可以进入解析状态,但如果我们有更多的状态,例如我们有 50 个不同的 URL,那么我们每次都必须放置权限:

<块引用>

["AuthService", 函数 (AuthService) {返回 AuthService.checkPermission().then(函数(数据){如果(!数据.活动){返回数据} 别的 {//REJECT 如果未授权 throw "Not Authorized";};}).catch(函数(错误){console.log("错误");抛出错误;});

所有这些代码都可以重构为一个服务:

app.service("permissionService",["AuthService", function (AuthService) {this.get = 函数 () {返回 AuthService.checkPermission().then(函数(数据){如果(!数据.活动){返回数据} 别的 {//如果未授权则拒绝抛出未授权";};}).catch(函数(错误){console.log("错误");抛出错误;});};}]);

然后在每个解析器中使用它:

//检查权限权限:[permissionService",功能(permissionService){返回permissionService.get();}];

通过重构代码,可以大大简化解析器.

I'm authenticating an angular app code given below, Basically I'm checking token from backend called if token is valid then we can allow users to view allowed page.

It's working somewhat but problem is when I'm going to /jobs page is somewhat loading then redirecting to login page but i don't want to show jobs page initially for few seconds it should be redirect quickly or it will not load jobs page.

In app.js

    var app = angular.module('ttt', ['ui.router', 'ui.bootstrap', 'ngResource', "ngStorage", "ngProgress", "ngCookies", 'angular-jwt', 'ngLodash','tagged.directives.infiniteScroll']);
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', "$httpProvider", function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
    $locationProvider.html5Mode(true);
    $urlRouterProvider.otherwise(function ($stateParams) {
        console.log("val check", $stateParams, window.location);
        window.location.href = "/undefined";

    });
    $stateProvider.state("jobs", {
        url: "/jobs",
        templateUrl: "views/dashboard.html",
        controller: "JobController as JobCtrl",
        resolve : {
            formInfo : ["AuthService",function (AuthService) {
                return AuthService.getFormInfo();
            }]
        }
    }).state("undefined", {
        url: "/undefined",
        templateUrl: "views/pagenotfound.html",
        bodyClass: "errors errors-404 errors-centered"
    }).state("login", {
        url: "/login",
        templateUrl: "views/login.html",
        controller: "LoginController as LoginCtrl",
        resolve : {
            formInfo : ["AuthService",function (AuthService) {
                return AuthService.getFormInfo();
            }]
        }
    })
}]);

app.run(['$rootScope', 'ngProgressFactory', '$state', '$compile', '$location', '$cookies', 'jwtHelper','AuthService', function ($rootScope, ngProgressFactory, $compile, $state, $location, $cookies, jwtHelper,AuthService) {
    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
        $rootScope.progressbar = ngProgressFactory.createInstance();
        $rootScope.progressbar.start();
        $rootScope.location = $location;
    });

  var authPreventer =  $rootScope.$on('$locationChangeStart', function (event, toState, toParams, fromState, fromParams, options) {

        var notCheckRoute = ["/undefined", "/signin", "/login"];
        //event.preventDefault();
         if(notCheckRoute.indexOf($location.path()) !== -1){
            AuthService.checkPermission()
            .then(function(data) {
                //event.preventDefault();
                if(data.active){
                    $location.path('/home'); 
                }else{
                    $location.path('/login');
                }
            });
         }else{
             //event.preventDefault();
            AuthService.checkPermission()
            .then(function(data) {
                if(!data.active){
                    $location.path('/login'); 
                }else{
                    //$location.path('/jobs'); 
                }
            });
         }
    });

    $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
        $rootScope.progressbar.complete();
        $rootScope.bodyClass = toState.bodyClass;
    });

    $rootScope.$on('$stateChangeError', function (event) {
        //$state.go('undefined');
    });
}]);

In service

    app.service('AuthService',['jwtHelper','$cookies','$location','$window','$http','$q',function (jwtHelper,$cookies,$location,$window,$http,$q) {

    this.login = function (token){
        var payload = jwtHelper.decodeToken(token);
    };

    this.logout = function (data) {

    };


var validatetoken = undefined;

this.checkPermission = function () {
    if (!validatetoken) {

        // create deferred object using $q
        var deferred = $q.defer();

        // get validatetoken form backend
        $http.post('/api/validatetoken', {token: $cookies.get('token')})
          .then(function(result) {
            // save fetched validatetoken to the local variable
            validatetoken = result.data;
            // resolve the deferred
            deferred.resolve(validatetoken);
          }, function(error) {
            validatetoken = error;
            deferred.reject(error);
          });
        // set the validatetoken object to be a promise until result comeback
        validatetoken = deferred.promise;
      }

      return $q.when(validatetoken);
}

    this.getFormInfo = function () {
         return $http.get("/api/getloginurl");
    }


}]);

解决方案

i don't want to show jobs page initially for few seconds it should be redirect quickly or it will not load jobs page.

When using the ui-router, avoid putting code in the $locationChangeStart block. This will cause conflicts with ui-router operation.

To prevent the jobs page from loading, check the authorization in the resolver for the state.

$stateProvider.state("jobs", {
    url: "/jobs",
    templateUrl: "views/dashboard.html",
    controller: "JobController as JobCtrl",
    resolve : {
        formInfo : ["AuthService",function (AuthService) {
            return AuthService.getFormInfo();
        }],
        //CHECK permission
        permission: ["AuthService", function (AuthService) {
            return AuthService.checkPermission()
              .then(function(data) {
                if(!data.active){
                    return data 
                } else {
                    //REJECT if not authorized
                    throw "Not Authorized";
                };
            }).catch(function(error) {
                console.log("ERROR");
                throw error;
            });
        }];
    }
})

By rejecting the resolve, the state change will be aborted and the page will not load.


Update

I can put in resolve state but if we have more state for example we have 50 different URL then every time do we have to put permission:

["AuthService", function (AuthService) { 
       return AuthService.checkPermission() 
         .then( function(data) { 
           if(!data.active){ 
               return data
           } else { 
               //REJECT if not authorized throw "Not Authorized";
           }; 
       }).catch( function(error) { 
           console.log("ERROR");
           throw error;
       });

All of that code can be re-factored into a service:

app.service("permissionService",["AuthService", function (AuthService) { 
    this.get = function () {
       return AuthService.checkPermission() 
         .then( function(data) { 
           if(!data.active){ 
               return data
           } else { 
               //REJECT if not authorized 
               throw "Not Authorized";
           }; 
       }).catch( function(error) { 
           console.log("ERROR");
           throw error;
       });
    };
}]);

Then use it in each resolver:

        //CHECK permission
        permission: ["permissionService", function (permissionService) {
            return permissionService.get();
        }];

By re-factoring the code, the resolver can be greatly simplified.

这篇关于使用 $locationChangeStart 进行 angularjs 身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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