将自定义服务插入 UI 路由
Plugging a custom service to UI Route
我开发了一个应用程序,它成功地使用 ADAL JS 库进行 Azure 身份验证。但是我还需要实现授权,我的意思是我需要限制特定组的视图。
我已经有一个 REST API,给定用户 ID 或电子邮件可以 return 我知道他所属的组。
但是我不确定如何插入一个 angular 服务来使用 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,其值为:
类似于:
url: "/dashboard_1",
templateUrl: "views/dashboard_1.html",
requireADLogin: true,
groups: "Admin, Accounting, Marketing"
然后后台的自定义服务将对此进行验证。
我不是特别熟悉 ADAL.js,但假设你可以在 http 请求中对服务器说 "does this user have any of these roles",那么你可以拦截 $stateChangeStart
,防止通过调用 event.preventDefault()
更改状态,询问服务器当前用户是否属于 toState
中指定的任何具有访问权限的角色,然后采取任何一种方式采取行动 - 发送到拒绝访问页面,或继续到 toState
.
以下是一个有缺陷的实现。工作版本被锁在工作中,我现在在家,但希望它能给你一些想法。
(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')));
我开发了一个应用程序,它成功地使用 ADAL JS 库进行 Azure 身份验证。但是我还需要实现授权,我的意思是我需要限制特定组的视图。
我已经有一个 REST API,给定用户 ID 或电子邮件可以 return 我知道他所属的组。
但是我不确定如何插入一个 angular 服务来使用 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,其值为:
类似于:
url: "/dashboard_1",
templateUrl: "views/dashboard_1.html",
requireADLogin: true,
groups: "Admin, Accounting, Marketing"
然后后台的自定义服务将对此进行验证。
我不是特别熟悉 ADAL.js,但假设你可以在 http 请求中对服务器说 "does this user have any of these roles",那么你可以拦截 $stateChangeStart
,防止通过调用 event.preventDefault()
更改状态,询问服务器当前用户是否属于 toState
中指定的任何具有访问权限的角色,然后采取任何一种方式采取行动 - 发送到拒绝访问页面,或继续到 toState
.
以下是一个有缺陷的实现。工作版本被锁在工作中,我现在在家,但希望它能给你一些想法。
(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')));