我正在使用angularJS和PHP开发一个网站。如果凭据有效且用户有效,则用户可以登录,PHP会设置会话并返回我存储在localStorage中的令牌。
我创建了一个检查令牌真实性的服务。我也有一个退出控制器。但我的注销功能无法正常工作。我删除本地存储令牌并销毁会话,然后导航到索引页面,但我仍然可以通过更改URL来查看其他页面。
这是我的登录控制器
(function() {
angular
.module('myApp.login', [])
.controller('LoginController', function($scope, $http, $location) {
var vm = this;
$scope.post = {};
$scope.post.login = [];
$scope.vm = {};
$scope.index = '';
var baseUrl = 'api/';
// function to submit the form after all validation has occurred
vm.login = function(isValid) {
// check to make sure the form is completely valid
if (isValid) {
$http({
method: 'post',
url: baseUrl + 'login',
data: $.param($scope.vm),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.success(function(data, status, headers, config) {
if (data.success) {
if (localStorage['token']) {
localStorage.removeItem('token');
}
localStorage.setItem("token", JSON.stringify(data.login_token));
$location.path('/home');
} else {
if (localStorage['token']) {
localStorage.removeItem('token');
}
vm.errorMessage = data.msg;
}
}).
error(function(data, status, headers, config) {
if (localStorage['token']) {
localStorage.removeItem('token');
}
vm.errorMessage = data.msg;
});
}
};
});
})();
登录成功后,请设置令牌。您可以在上面看到然后我将用户重定向到 Home Controller ,如下所示:
-(function() {
angular
.module('myApp.home', [])
.factory('myHomeService', function($http) {
var baseUrl = 'api/';
return {
getUserSessInfo: function() {
return $http.get(baseUrl + 'get_user_session');
}
};
})
.controller('HomeController', function($scope, $routeParams, myHomeService, AuthService) {
var vm = this;
var token;
if (localStorage['token']) {
token = JSON.parse(localStorage['token']);
} else {
token = "";
}
if (token) {
AuthService.checkToken(token);
//To get user session value
myHomeService.getUserSessInfo().success(function(data) {
vm.id = data.id;
//vm.userName = data.username;
});
$scope.logout = function() {
var data = {
token: token
}
AuthService.logOut(token);
}
});
})();
在家庭控制器中,我检查令牌并调用进行用户身份验证的服务AuthService
。
这是 AuthService 。它有两个功能。一个用于检查令牌,另一个用于注销。
(function() {
angular
.module('myApp.AuthenticationService', [])
.factory('AuthService', ["$http", "$location", function($http, $location){
var vm = this;
var baseUrl = 'api/';
vm.checkToken = function(token)
{
var data = {token: token};
$http.post(baseUrl + 'validateUserToken', data).success(function(response)
{
if (response.msg === "unauthorized")
{
//console.log("Logged out");
$location.path('/login');
}
else
{
//console.log("Logged In");
return response.msg;
}
}).error(function(error)
{
$location.path('/login');
})
}
vm.logOut = function(token)
{
var data = {token: token};
$http.post(baseUrl + 'destroyUserToken', data).success(function(response)
{
if (response.msg === "Logged out")
{
localStorage.clear();
//console.log("Logged out");
$location.path('/login');
}
}).error(function(error)
{
localStorage.clear();
$location.path('/login');
})
}
return vm;
}]);
})();
当用户点击注销链接时,会调用注销控制器。这是:
(function() {
angular
.module('myApp.logout', [])
.controller('LogoutController', function($scope, $routeParams, AuthService) {
var vm = this;
//If user is not logged in
var token;
if (localStorage['entrp_token']) {
token = JSON.parse(localStorage['entrp_token']);
} else {
token = "something stupid";
}
AuthService.logOut(token);
});
})();
但即使完成所有这些操作,用户也可以通过更改网址导航到较旧的网页。我该如何防止这种情况?
答案 0 :(得分:1)
您可以在路线上使用resolve
来确定用户是否已登录或在呈现模板之前没有。
检查此Fiddle以了解如何操作
var onlyLoggedIn = function ($location,$q,Auth) {
var deferred = $q.defer();
if (Auth.isLogin()) {
deferred.resolve();
} else {
deferred.reject();
$location.url('/login');
}
return deferred.promise;
};
angular.module('YourModule')
.factory('Auth', function() {
var isLogin = function() {
console.log(localStorage.isLogged)
return localStorage.isLogged === "true";
}
return {isLogin: isLogin}
})
.config(function ($routeProvider) {
$routeProvider.
when('/home', {
templateUrl: 'embedded.home.html',
controller: 'HomeController'
}).
when('/about', {
templateUrl: 'embedded.about.html',
controller: 'AboutController',
resolve: {loggedIn: onlyLoggedIn}
}).
otherwise({
redirectTo: '/home'
});
});
答案 1 :(得分:0)
您需要在路由期间处理事情。当用户未登录且请求的页面另有要求时,您应该重定向到其他页面,例如“Unauthorized.html”或类似内容。
我正在使用$routeProvider
进行路由。我没有尝试过使用有角度的ui-router,如果这不适合你的需要请原谅我。
我在路由中添加了一个属性loginRequired
以及requiredRoles
,以确定当前用户是否可以访问特定页面。
使用$routeChangeStart
我正在检查是否满足页面条件,例如当前用户是否已登录并且有权访问该页面。如果不符合条件,我会导航到另一页。
从我的旧项目中提取的代码:
.config(["$locationProvider", "$routeProvider", "$httpProvider", "KeepaliveProvider", "IdleProvider",
function ($locationProvider, $routeProvider, $httpProvider, KeepaliveProvider, IdleProvider) {
var templateLocation = "/Templates";
$locationProvider.html5Mode({
enabled: true,
requireBase: true,
rewriteLinks: true
}).hashPrefix("#");
$routeProvider
.when("/", {
templateUrl: templateLocation + "/Home.html", //"/Product-List.html", //
controller: "HomeController", //"ProductController", //
loginRequired: false,
requiredRoles: []
})
.when("/Report", {
templateUrl: templateLocation + "/Report.html",
controller: "ReportController",
loginRequired: true,
requiredRoles: ["Admin"]
})
.when("/About", {
templateUrl: templateLocation + "/About.html",
controller: "AboutController",
loginRequired: false,
requiredRoles: []
})
.when("/Contact", {
templateUrl: templateLocation + "/Contact.html",
controller: "ContactController",
loginRequired: false,
requiredRoles: []
})
.when("/Register", {
templateUrl: templateLocation + "/Register.html",
controller: "RegisterController",
loginRequired: false,
requiredRoles: []
})
.when("/Login", {
templateUrl: templateLocation + "/Login.html",
controller: "LoginController",
loginRequired: false,
requiredRoles: []
})
.when("/User-List", {
templateUrl: templateLocation + "/User-List.html",
controller: "UserController",
loginRequired: true,
requiredRoles: ["Admin", "Secretary"]
})
.when("/User-Profile/:userId", {
templateUrl: templateLocation + "/User-Profile.html",
controller: "UserController",
loginRequired: true,
requiredRoles: []
})
.when("/TermsAndCondition", {
templateUrl: templateLocation + "/Terms-And-Condition.html",
controller: "SupportController",
loginRequired: false,
requiredRoles: []
})
.when("/EmailConfirmed", {
templateUrl: templateLocation + "/EmailConfirmed.html",
controller: "SupportController",
loginRequired: false,
requiredRoles: []
})
.when("/ResetPassword", {
templateUrl: templateLocation + "/ResetPassword.html",
controller: "SupportController",
loginRequired: false,
requiredRoles: []
})
.when("/ForgotPassword", {
templateUrl: templateLocation + "/ForgotPassword.html",
controller: "SupportController",
loginRequired: false,
requiredRoles: []
})
.when("/Unauthorized", {
templateUrl: templateLocation + "/Unauthorized.html",
controller: "UnauthorizedController",
loginRequired: false,
requiredRoles: []
})
.when("/ErrorHandler", {
templateUrl: templateLocation + "/ErrorHandler.html",
controller: "ErrorController",
loginRequired: false,
requiredRoles: []
})
.otherwise({
templateUrl: templateLocation + "/Error404.html",
controller: "ErrorController",
loginRequired: false,
requiredRoles: []
});
}])
.run(["$q", "$rootScope", "$location", "AccountService", "Idle", function ($q, $rootScope, $location, AccountService, Idle) {
Idle.watch();
var templateLocation = "/Templates";
var postLogInRoute;
$rootScope.$on("$routeChangeStart", function (event, nextRoute, currentRoute) {
if (AccountService.isLoggedIn() &&
(nextRoute.templateUrl == templateLocation + "/Register.html" ||
nextRoute.templateUrl == templateLocation + "/Login.html")) {
$location.path("/Unauthorized").replace();
postLogInRoute = $location.path();
}
else if (nextRoute.loginRequired && !AccountService.isLoggedIn()) {
$location.path("/Login").replace();
postLogInRoute = $location.path();
}
else if (nextRoute.templateUrl.length != templateLocation + "/Unauthorized.html" && !AccountService.isUserAuthorized(nextRoute.requiredRoles)) {
$location.path("/Unauthorized").replace();
postLogInRoute = $location.path();
}
//else if (postLogInRoute && AccountService.isLoggedIn()) {
// $location.path(postLogInRoute).replace();
// postLogInRoute = null;
//}
else {
// Do nothing
}
});
}])