AngularJS - 访问动态生成的状态

时间:2018-06-18 23:33:23

标签: javascript angularjs angular-ui-router

我正在为我的网络应用程序开发密码重置功能,用户可以通过提供有效的电子邮件地址重置密码。

在提供有效输入后,将向给定的电子邮件地址发送一封电子邮件,其中包含重置密码的链接,在这种特殊情况下,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 *

0 个答案:

没有答案