Angular js / ui-router / 限制用户手动导航到 url (view)

Angular js / ui-router / restrict user from manually navigating to url (view)

我花了一整天的时间(业余程序员,不是真正的程序员)。我首先承认问题是我对 angular 的基本原理缺乏理解(以及与此相关的大多数编程)。我对网络开发特别陌生,需要一些帮助。

无论如何,我有一个用于学习目的的模板,仅此而已。这是 startangular.com 中的 'ani-theme'。我构建了一些基本逻辑来验证用户(在电子邮件中输入 'aaa' 哈哈,记住,它只是为了学习)。此代码工作正常,如果输入 'aaa' 则将触发路由器将您移至仪表板。

问题是用户只需将仪表板的 URL 放入浏览器中即可转到那里。

我有一个名为 "authed" 的变量,一旦他们登录就设置为 true,但我似乎无法 'conditionally route' 用户在仪表板中键入 URL手动。我尝试了很多东西,但没有运气。

经过 5 小时的研究,我认为这是由于 angular 的异步性质或范围问题。或两者。可能两者都不是。 idk.

我看到了很多关于 $stateChangeStart 的其他帖子,但它让我难以理解。有人可以在这里指出我正确的方向,或者尝试用虚拟术语解释这里发生的事情。我是认真的,我真的不懂那么多,所以低调一点,我不会被侮辱。

APP.JS

var authed = false;
var done = false;
var yapp = angular
  .module('yapp', [
    'ui.router',
    'ngAnimate',
    'myAuth'
  ])
  .config(function($stateProvider, $urlRouterProvider) {


      $urlRouterProvider.when('/dashboard', '/dashboard/overview');
      $urlRouterProvider.otherwise('/login');

    $stateProvider
      .state('base', {
        abstract: true,
        url: '',
        templateUrl: 'views/base.html'
      })
      .state('login', {
        url: '/login',
        parent: 'base',
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl'
      })
      .state('dashboard', {
        url: '/dashboard',
        parent: 'base',
        templateUrl: 'views/dashboard.html',
        controller: 'DashboardCtrl'
      })
      .state('overview', {
        url: '/overview',
        parent: 'dashboard',
        templateUrl: 'views/dashboard/overview.html'
      })
      .state('reports', {
        url: '/reports',
        parent: 'dashboard',
        templateUrl: 'views/dashboard/reports.html'
      });

  });

LOGIN.JS

angular.module('yapp')
  .controller('LoginCtrl', function($scope, $location, authFactory) {
      $scope.submit = function(emailp) {
        if(authFactory.checkAuth(emailp)) {
          $location.path('/dashboard');
        }else{
          alert("WRONG");
        }
      }
    });

AUTH.JS

var myAuth = angular.module('myAuth', [])
  .factory('authFactory', function(){
    var factory = {};
    factory.checkAuth = function(emailp){
      if(emailp == 'aaa') authed = true;
      return(authed);
    };
    return factory;
  });

重要附注

我喜欢建议和帮助,所以如果你看到我正在做的其他事情看起来很荒谬,请给我打电话。对我有很大帮助。

-------------------------------------------- ---

编辑编辑编辑编辑编辑

感谢您到目前为止的回答!我将尝试实现@swestner 的答案,一旦它起作用,我将研究 'why' 部分,这样我才能真正理解。

关于同一问题,我还有另一个问题需要澄清,以便我能更好地理解为什么我的其他方法不起作用。我很好奇,因为这是一种奇怪的行为。

因此,您看到我的 authed 变量在 app.js 中声明,然后在 auth.js 工厂中根据用户 'emailp' 将其设置为 true 或 false。 我在 app.js 中添加了一些逻辑,说“如果 authed 为真,则使用这些路由命令,否则使用这些命令。

示例:

console.log(authed) //this actually does print the correct value...
if(authed) {  //however this doesnt work!
  $urlRouterProvider.when('/dashboard', '/dashboard/overview');
  $urlRouterProvider.otherwise('/login');
}else{
  $urlRouterProvider.when('/dashboard', '/login');
  $urlRouterProvider.otherwise('/login');
}

我可以打印正确的值,但条件始终为真。

但是,如果我在条件语句之前声明变量 authed2 RIGHT,它就可以正常工作!

var authed2 = true;

console.log(authed + " #1");
console.log(authed2 + ' #2');

if(authed2) {
  $urlRouterProvider.when('/dashboard', '/dashboard/overview');
  $urlRouterProvider.otherwise('/login');
}else{
  $urlRouterProvider.when('/dashboard', '/login');
  $urlRouterProvider.otherwise('/login');
}

程序知道这两个值都是真的,我什至可以在条件之前打印它们,但是当我使用 authed(在别处设置和声明)时,条件不起作用(即使它似乎知道答案) .

这让我很困惑,我必须在这里遗漏一些背景行为。

$stateChangeStart 事件是处理此问题的适当位置。当您尝试导航到 url 时,将触发此事件。届时您可以检查用户是否已通过身份验证,如果未通过身份验证,则将其退回登录。

您可以这样安排活动:

angular
  .module('yapp')
  .run(function ($rootScope, $state, authFactory) {
    $rootScope.$on('$stateChangeStart', function () {
      if(!authFactory.isAuthed()){
        $state.go('login')
      }
    })
  });

并更新您的身份验证工厂以使用 isAuthed 方法。

var myAuth = angular.module('myAuth', [])
  .factory('authFactory', function () {
    var factory = {};
    factory.checkAuth = function (emailp) {
      if (emailp == 'aaa') authed = true;
      return (authed);
    };

    factory.isAuthed = function () {
      return authed;
    }
    return factory;
  });