我正在为我的网络应用程序开发密码重置功能,用户可以通过提供有效的电子邮件地址重置密码。
在提供有效输入后,将向给定的电子邮件地址发送一封电子邮件,其中包含重置密码的链接,在这种特殊情况下,URL将如下所示:http://localhost:8080/account/reset/:token
,其中令牌是随机的为该特定用户保存在数据库中的生成令牌。
我的后端工作正常,已发送电子邮件并在数据库中进行了更改。
问题依赖于我的前端。我通过为我的公共页面声明一个数组来保护我的路由器状态。如果在此阵列中找不到路由器状态或用户未登录或JWT已过期,则用户将被重定向回登录页面。
现在我的问题是,由于令牌是动态生成的,我无法访问重置页面,而是被重定向到登录页面。有没有办法在publicPages
数组中声明一张外卡,或者解决这个问题的最佳方法是什么?
以下是我目前所尝试的内容。
app.js
(function () {
'use strict';
angular
.module('app', [ 'ui.router', 'ngStorage', 'ngCookies', 'angular-jwt'])
.config(config)
.run(run);
function config($qProvider, $stateProvider, $urlRouterProvider, $locationProvider, $httpProvider, $translateProvider, stateList) {
$qProvider.errorOnUnhandledRejections(false);
$locationProvider.html5Mode(true).hashPrefix('!');
// Loop through states from states.js
for(var i = 0; i < stateList.length; i++ ) {
$stateProvider.state(stateList[i].name, stateList[i].value);
}
// default route
$urlRouterProvider.otherwise("/");
}
function run($rootScope, $http, $localStorage, $state, $stateParams, jwtHelper, $location) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
// if user is found from the Local Storage, keep user logged in by automatically setting the "Authorization" header in future requests
if ($localStorage.currentUser) {
$http.defaults.headers.common.Authorization = 'Bearer ' + $localStorage.currentUser.token;
}
// check authentication on every page request
$rootScope.$on('$locationChangeStart', function (event, next, current) {
// declare public states (routes that are available without authentication)
var publicPages = [
'/account/login',
'/account/recover',
'/account/reset/:token'
];
// secured states (all the pages that are not inside the publicPages array)
var restrictedPage = publicPages.indexOf($location.path()) === -1;
// redirect user to login page if user is not logged in or the JWT token is expired
if (restrictedPage && (!$localStorage.currentUser || jwtHelper.isTokenExpired($localStorage.currentUser.token)) ) {
$location.path('/account/login');
}
});
}
})();
states.js
(function() {
'use strict';
var stateList =
[
{
name: "account",
value: {
templateUrl: "/angular/app-components/auth/index.view.html",
abstract: true
}
},
{
name: "account.login",
value: {
title: "Sign in",
url: "/account/login",
templateUrl: "/angular/app-components/auth/login/index.view.html",
controllerAs: "vm",
controller: "Login.IndexController",
}
},
{
name: "account.recover",
value: {
title: "Recover account",
url: "/account/recover",
templateUrl: "/angular/app-components/auth/password/recover/index.view.html",
controller: "Password.IndexController",
controllerAs: "vm",
}
},
{
name: "account.reset",
value: {
title: "Reset account",
url: "/account/reset/:token",
templateUrl: "/angular/app-components/auth/password/reset/index.view.html",
controller: "Password.IndexController",
controllerAs: "vm",
}
}
];
angular
.module('app')
.constant('stateList', stateList);
})();
修改
我设法让这个工作。我刚刚在我的状态对象中添加了一个名为authenticate
的新对象,用于我想要保护的路由。然后,我使用$rootScope.$on('$locationChangeStart')
而不是$rootScope.$on('$stateChangeStart')
...而不是$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if (toState.authenticate && (!$localStorage.currentUser || jwtHelper.isTokenExpired($localStorage.currentUser.token))){
// User isn’t authenticated
$location.path("/account/login");
event.preventDefault() // important
}
});
。
以下是一个例子:
app.js
(function() {
'use strict';
var stateList =
[
{
name: "dashboard",
value: {
templateUrl: "/angular/app-components/dashboard/index.view.html",
controller: "Dashboard.IndexController",
controllerAs: "vm",
abstract: true
}
},
{
name: "dashboard.app",
value: {
title: "Dashboard",
url: "/app/dashboard",
authenticate: true
}
},
{
name: "account",
value: {
templateUrl: "/angular/app-components/auth/index.view.html",
abstract: true
}
},
{
name: "account.login",
value: {
title: "Sign in",
url: "/account/login",
templateUrl: "/angular/app-components/auth/login/index.view.html",
controllerAs: "vm",
controller: "Login.IndexController"
}
},
{
name: "account.recover",
value: {
title: "Recover account",
url: "/account/recover",
templateUrl: "/angular/app-components/auth/password/recover/index.view.html",
controller: "Password.IndexController",
controllerAs: "vm"
}
},
{
name: "account.reset",
value: {
title: "Reset account",
url: "/account/reset/:token",
templateUrl: "/angular/app-components/auth/password/reset/index.view.html",
controller: "Password.IndexController",
controllerAs: "vm"
}
}
];
angular
.module('app')
.constant('stateList', stateList);
})();
states.js
char *