Php $stateChangeStart在从Rest API获取数据之前运行
我尝试进行用户登录身份验证,我使用方法Php $stateChangeStart在从Rest API获取数据之前运行,php,angularjs,authentication,angular-ui-router,Php,Angularjs,Authentication,Angular Ui Router,我尝试进行用户登录身份验证,我使用方法isAuthenticated创建了一个名为AuthService的服务,在该方法中,我调用API来交叉检查用户是否登录(稍后我还会使用其中的用户角色),然后我在$rootScope.$on中调用这个服务,但这不是等到我的服务从API中获取数据,这是我的app.js var app = angular.module('myApp', ['ngRoute', 'ui.router', 'ngAnimate', 'toaster', 'ui.bootstrap'
isAuthenticated
创建了一个名为AuthService
的服务,在该方法中,我调用API来交叉检查用户是否登录(稍后我还会使用其中的用户角色),然后我在$rootScope.$on
中调用这个服务,但这不是等到我的服务从API中获取数据,这是我的app.js
var app = angular.module('myApp', ['ngRoute', 'ui.router', 'ngAnimate', 'toaster', 'ui.bootstrap']);
app.config(['$routeProvider', '$locationProvider', '$stateProvider', '$urlRouterProvider',
function ($routeProvider, $locationProvider, $stateProvider, $urlRouterProvider) {
$stateProvider.
state('/', {
url: "/",
views: {
header: {
templateUrl: 'partials/common/header.html',
controller: 'authCtrl',
},
content: {
templateUrl: 'partials/dashboard.html',
controller: 'authCtrl',
}
},
title: 'Dashboard',
authenticate: true
})
.state('login', {
url: "/login",
views: {
content: {
templateUrl: 'partials/login.html',
controller: 'authCtrl',
}
},
title: 'Login',
authenticate: false
})
.state('dashboard', {
title: 'Dashboard',
url: "/dashboard",
views: {
header: {
templateUrl: 'partials/common/header.html',
controller: 'authCtrl',
},
content: {
templateUrl: 'partials/dashboard.html',
controller: 'authCtrl',
}
},
authenticate: true
});
$urlRouterProvider.otherwise("/");
//check browser support
if(window.history && window.history.pushState){
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
}
}])
.run(function ($rootScope, $location, $state, Data, AuthService) {
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
$rootScope.title = toState.title;
$rootScope.authenticated = false;
var userInfo = AuthService.isAuthenticated();
if (toState.authenticate && !AuthService.isAuthenticated()){
// User isn’t authenticated
$state.transitionTo("login");
event.preventDefault();
} else {
alert('here I am ='+$rootScope.authenticated);
}
});
});
这是我的服务
app.factory('AuthService', function ($http, Data, $rootScope) {
var authService = {};
authService.isAuthenticated = function () {
Data.get('index.php/api/authentication/is_login').then(function (results) {
if (results.uid) {
$rootScope.authenticated = true;
$rootScope.uid = results.uid;
$rootScope.name = results.name;
$rootScope.email = results.email;
return results.uid;
} else {
return false;
}
});
}
return authService;
});
尝试了很多东西,但到目前为止没有运气,请建议一个最好的方法,我在ui路由中尝试了解决方法,但没有成功
提前感谢。由于
Data.get()
函数返回一个承诺,因此是异步的,因此当前的实现将无法工作。因此,路由更改将继续进行,而无需等待身份验证服务返回任何值
要解决您的问题,您应该以特定的方式处理此异步逻辑:
app.run(function ($rootScope, $location, $state, Data, AuthService) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
/**
* If the user is heading towards a state that requires
* authentication, assume that they are not authenticated,
* and stop them! Otherwise, let them through...
*/
if (toState.authenticate) {
event.preventDefault();
if (toState.name !== fromState.name) {
// Now check whether or not they are authenticated
AuthService.isAuthenticated().then(function () {
// Yes! They're authenticated, continue
$state.go(toState.name, toParams);
}, function () {
// Nope, this user cannot view this page
alert('You cannot view this page!');
});
}
} else {
return;
}
});
}
编辑:我添加了一个检查语句toState.name!==fromState.name
来中断任何重定向循环,从而可能导致对身份验证服务的无休止调用。这是对该期原始海报评论的回应
默认情况下,诀窍是防止路由转换。然后,在允许用户进一步移动之前,您可以执行所需的异步逻辑
我建议添加微调器或加载窗口,以提醒用户您正在执行此身份验证检查。防止用户在页面上进行任何进一步的操作也是明智的,但这完全取决于您
请注意,函数AuthService.isAuthenticated()
现在返回一个Promise
,您必须对身份验证服务进行一个小的更改才能实现这一点。只需将当前逻辑包装如下:
app.factory('AuthService', function ($http, Data, $rootScope, $q) {
var authService = {};
authService.isAuthenticated = function () {
return $q(function (resolve, reject) {
Data.get('index.php/api/authentication/is_login').then(function (results) {
if (results.uid) {
$rootScope.authenticated = true;
$rootScope.uid = results.uid;
$rootScope.name = results.name;
$rootScope.email = results.email;
// Great, the user is authenticated, resolve the Promise
resolve(results.uid);
} else {
// The user does not appear to be authenticated, reject the Promise
reject();
}
});
});
};
return authService;
});
我希望这能解决你的问题,承诺可能是一种痛苦,但也可能是一种非常强大的工具。GitHub上有一个很好的帖子,讨论了许多关于这个问题的潜在解决方案,可以在这里找到:
$q
:
你为什么用php
标记这个问题?因为我正在使用codeigniter进行rest,非常感谢你的回复。我已经实现了它&在我的控制台TypeError中出错:无法读取未定义的属性'then'。您是否更新了AuthService.isAuthenticated()
,以便它返回一个承诺
?是的,我更改了我的服务,现在,如果用户已登录,我的http请求将返回用户数据&如果用户未登录,则返回一个空白对象。我们已修复错误“无法读取未定义的属性'then'”,但当http请求对任何用户进行身份验证时,它将重定向到$state.go(toState.name,toParams);,它进入无限循环以发出call http请求来验证用户。您可以添加一个检查,通过在调用AuthService之前添加一个检查来确认该状态确实与上一个状态不同。isAuthenticated()
,我将更新帖子。