我正在使用MEAN堆栈进行基于令牌的身份验证。我的应用程序必须显示Home,Signin和Signup,当没有令牌存在时,即当用户没有登录时,Home,Me和Logout,当有令牌即用户登录时。我的所有服务器端功能都正常工作登入,注册,注销。地址栏中的URL重定向和视图呈现正确发生,但菜单项未相应更新。仅在我点击手动刷新时才更新。请帮忙!
Index.html(略去的包括):
<body ng-app="app">
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation" data-ng-controller="authCtrl">
<!-- data-ng-controller="authCtrl" -->
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#/">Angular Restful Auth</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a ng-href="#/">Home</a></li>
<li data-ng-show="token"><a ng-href="#/me">Me</a></li>
<li data-ng-hide="token"><a ng-href="#/login">Signin</a></li>
<li data-ng-hide="token"><a ng-href="#/register">Signup</a></li>
<li data-ng-show="token"><a ng-click="logout()">Logout</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container" ng-view="">
</div> <!-- /container -->
</body>
app.js:
'use strict';
var app = angular.module('app', ['ngRoute', 'authControllers', 'authServices']);
var authControllers = angular.module('authControllers', []);
var authServices = angular.module('authServices', []);
var options = {};
options.api = {};
//dev URL
options.api.base_url = "http://localhost:3000";
app.config(['$locationProvider', '$routeProvider',
function($location, $routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/home.html',
controller: 'authCtrl'
}).
when('/login', {
templateUrl: 'partials/signin.html',
controller: 'authCtrl'
}).
when('/register', {
templateUrl: 'partials/signup.html',
controller: 'authCtrl'
}).
when('/me', {
templateUrl: 'partials/me.html',
controller: 'authCtrl'
}).
otherwise({
redirectTo: '/'
});
}]);
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push('TokenInterceptor');
}]);
app.run(function($rootScope, $location, $window, AuthenticationService) {
$rootScope.$on("$routeChangeStart", function(event, nextRoute, currentRoute) {
//redirect only if both isAuthenticated is false and no token is set
if (nextRoute != null && nextRoute.access != null && nextRoute.access.requiredAuthentication
&& !AuthenticationService.isAuthenticated && !$window.sessionStorage.token) {
$location.path("/login");
}
});
});
authControllers.js:
authControllers.controller('authCtrl', ['$scope', '$location', '$window', 'UserService', 'AuthenticationService',
function authCtrl($scope, $location, $window, UserService, AuthenticationService) {
//Admin User Controller (login, logout)
$scope.logIn = function logIn(username, password) {
if (username !== undefined && password !== undefined) {
UserService.logIn(username, password).success(function(data) {
AuthenticationService.isLogged = true;
$window.sessionStorage.token = data.token;
$location.path("/me");
}).error(function(status, data) {
console.log(status);
console.log(data);
});
}
}
$scope.token = $window.sessionStorage.token;
$scope.me = function() {
UserService.me(function(res) {
$scope.myDetails = res;
}, function() {
console.log('Failed to fetch details');
$rootScope.error = 'Failed to fetch details';
})
};
$scope.logout = function logout() {
if (AuthenticationService.isAuthenticated) {
UserService.logOut().success(function(data) {
AuthenticationService.isAuthenticated = false;
delete $window.sessionStorage.token;
$location.path("/");
}).error(function(status, data) {
console.log(status);
console.log(data);
});
}
else {
$location.path("/login");
}
}
$scope.register = function register(username, password, passwordConfirm) {
if (AuthenticationService.isAuthenticated) {
$location.path("/me");
}
else {
UserService.register(username, password, passwordConfirm).success(function(data) {
$location.path("/login");
}).error(function(status, data) {
console.log(status);
console.log(data);
});
}
}
}]);
答案 0 :(得分:1)
$scope.token = $window.sessionStorage.token;
此字符串不会将令牌绑定到存储属性。您应该每次更新范围变量,如果您不在摘要循环中,则显式调用apply。
答案 1 :(得分:0)
实际上我尝试了一种不同的方法,甚至更好地在全球范围内做一次。在我的控制器中注入$ rootScope并分配了SessionStorage令牌值。现在它就像一个简单更改的魅力,而无需在多个位置更新$ scope变量。
authControllers.controller('authCtrl', ['$rootScope','$scope', '$location', '$window', 'UserService', 'AuthenticationService',
function authCtrl($rootScope,$scope, $location, $window, UserService, AuthenticationService) {
$rootScope.token = $window.sessionStorage.token;
}]);