【问题标题】:Plugging a custom service to UI Route将自定义服务插入 UI Route
【发布时间】:2015-06-24 06:09:16
【问题描述】:

我开发了一个应用程序,它成功地使用 ADAL JS 库通过 azure 进行身份验证。但是我还需要实现授权,我的意思是我需要将视图限制在特定的组中。

我已经有一个 REST API,给定用户 ID 或电子邮件可以返回我他所属的组。

但是我不确定如何插入一个角度服务来使用该 REST API 并将其插入到路由配置中。

app.js

(function () {
    angular.module('inspinia', [
        'ui.router',                    // Routing
        'oc.lazyLoad',                  // ocLazyLoad
        'ui.bootstrap',                 // Ui Bootstrap
        'pascalprecht.translate',       // Angular Translate
        'ngIdle',                       // Idle timer
        'AdalAngular',                  // ADAL JS Angular
        'ngRoute'                       // Routing
    ])
})();

config.js

function config($stateProvider, $urlRouterProvider, $ocLazyLoadProvider, IdleProvider, KeepaliveProvider,adalAuthenticationServiceProvider, $httpProvider) {

    // Configure Idle settings
    IdleProvider.idle(5); // in seconds
    IdleProvider.timeout(120); // in seconds

    $urlRouterProvider.otherwise("/dashboards/dashboard_1");

    $ocLazyLoadProvider.config({
        // Set to true if you want to see what and when is dynamically loaded
        debug: false
    });

    $stateProvider

        .state('dashboards', {
            abstract: true,
            url: "/dashboards",
            templateUrl: "views/common/content.html",
        })
        .state('dashboards.dashboard_1', {
            url: "/dashboard_1",
            templateUrl: "views/dashboard_1.html",
            requireADLogin: true,
            resolve: {
                loadPlugin: function ($ocLazyLoad) {
                    return $ocLazyLoad.load([
                        {

                            serie: true,
                            name: 'angular-flot',
                            files: [ 'js/plugins/flot/jquery.flot.js', 'js/plugins/flot/jquery.flot.time.js', 'js/plugins/flot/jquery.flot.tooltip.min.js', 'js/plugins/flot/jquery.flot.spline.js', 'js/plugins/flot/jquery.flot.resize.js', 'js/plugins/flot/jquery.flot.pie.js', 'js/plugins/flot/curvedLines.js', 'js/plugins/flot/angular-flot.js', ]
                        },
                        {
                            name: 'angles',
                            files: ['js/plugins/chartJs/angles.js', 'js/plugins/chartJs/Chart.min.js']
                        },
                        {
                            name: 'angular-peity',
                            files: ['js/plugins/peity/jquery.peity.min.js', 'js/plugins/peity/angular-peity.js']
                        }
                    ]);
                }
            }
        })

理想情况下,我可以为每个状态添加一个新属性,称为 Groups with values:

类似:

 url: "/dashboard_1",
                templateUrl: "views/dashboard_1.html",
                requireADLogin: true,
                groups: "Admin, Accounting, Marketing"

然后后台的自定义服务将验证这一点。

【问题讨论】:

    标签: javascript angularjs azure adal adal.js


    【解决方案1】:

    我对 ADAL.js 并不特别熟悉,但是假设您可以在 http 请求中对服务器说“此用户是否具有这些角色中的任何一个”,那么您可以拦截 $stateChangeStart,阻止状态通过调用event.preventDefault() 进行更改,询问服务器当前用户是否处于toState 中指定的任何角色中作为具有访问权限,然后采取任何一种方式 - 发送到拒绝访问页面,或继续访问@987654324 @。

    以下是有缺陷的实现。工作版本在工作中被锁定,我现在在家,但希望它能给你一些想法。

    (function (app) {
      "use strict";
    
      app.run(run);
    
      function run($rootScope, $log, $state, $q, authService) {
    
        /**
         * The canceller is passed to the authService.isTokenValid()
         *
         * The canceller is a promise, that, when resolved, cancels the current
         * token validation request
         */
        let _canceller;
    
        /**
         * When state is changed, ensure that the current user has access
         * @param event
         * @param toState
         */
        function onStateChangeStart(event, toState, toParams) {
    
          // When token is valid, continue with navigation to the state
          function onValidToken() {
            if (toState.name === 'login'){
              $state.go('home');
            } else {
              $state.go(toState, toParams, {notify: false}).then((state) => {
                $rootScope.$broadcast('$stateChangeSuccess', state, null);
              });
            }
          }
    
          // When the token is not valid, set state to login
          function onInvalidToken() {
            if (toState.name === 'login'){
              $state.go(toState, toParams, {notify: false}).then((state) => {
                $rootScope.$broadcast('$stateChangeSuccess', state, null);
              });
            } else {
              $log.warn(`Access denied to state ${toState.name}`);
              $state.go('login');
            }
          }
    
          // On completion of token validation, resolve the canceller
          function onFinally() {
            if (_canceller) {
              _canceller.resolve();
            }
          }
    
          // If the state requiresLogin
          if (toState.requiresLogin || toState.name === 'login') {
    
            // stop navigation
            event.preventDefault();
    
            // Cancel any current requests
            if (_canceller) {
              _canceller.resolve();
            }
    
            // create a new promise
            _canceller = $q.defer();
    
            // validate
            authService.isTokenValid(_canceller)
              .then(onValidToken, onInvalidToken)
              .finally(onFinally);
          }
        }
    
        $rootScope.$on('$stateChangeStart', onStateChangeStart);
    
    
    
      }
    
    }(angular.module('app.features')));

    【讨论】:

    • 我了解您的代码,但我不明白将 http 调用放在我的服务的位置。
    • 在示例中,authService.isTokenValid 是发出 http 请求的位置。
    • 因为我对 angularjs 语法有点菜鸟,你能告诉我如何将它插入到我的 app.js 中吗?
    • 你能详细说明一下吗?你指的是角度run
    • 是的,函数运行如何将它插入我的 app.js 或 config.js?
    猜你喜欢
    • 2016-09-02
    • 1970-01-01
    • 2017-07-27
    • 2012-09-25
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    相关资源
    最近更新 更多