【问题标题】:How to globally implement Authentication with AngularJS, Devise and UI Router?如何使用 AngularJS、Devise 和 UI Router 全局实现身份验证?
【发布时间】:2015-03-16 10:10:58
【问题描述】:

我对 Angular 很陌生,所以这可能是一个新手问题。

我正在尝试实现一个简单的任务管理器(只是一个练习),其中 Rails 作为后端,Angular 作为前端。到目前为止,我遵循了一个教程,一切正常。

现在我想全局实现身份验证。这意味着:当用户没有注册和登录时,她应该看到一个启动页面或登录页面。

我不想在每个 Angular 控制器中都这样做,因为 DRY。所以我认为 UI 路由器可能是一个好地方。而且我有点怀疑 $httpProvider.interceptors 可能有用。

这就是我得到的。我可以检查用户是否经过身份验证并阻止页面加载。但仅此而已。我将如何离开这里?有没有我错过的好教程?

Stackoverflow 上的This question 也朝着类似的方向发展,但并没有解决我的问题,因为他们没有使用 Devise。

谢谢!

// app.js
var app = angular.module("TaskManager", ['ui.router', 'templates', 'Devise'])
.config([
    '$stateProvider',
    '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider){
        $stateProvider
            .state('home', {
                url: '/home',
                templateUrl: 'home/_home.html',
                controller: 'MainCtrl', 
                resolve: {
                    projectPromise: ['projects', function(projects) {
                        console.log($rootScope);
                        return projects.getAll();
                    }]
                }
            })
            .state('projects', {
                url: '/projects/{id}',
                templateUrl: 'projects/_projects.html',
                controller: 'ProjectsCtrl',
                resolve: {
                    project: ['$stateParams', 'projects', function($stateParams, projects) {
                        return projects.get($stateParams.id);
                    }]
                }
            })
            .state('login', {
                url: '/login',
                templateUrl: 'auth/_login.html',
                controller: 'AuthCtrl',
                onEnter: ['$state', 'Auth', function($state, Auth) {
                    Auth.currentUser().then(function() {
                        $state.go('home');
                    })
                }]
            })
            .state('register', {
                url: '/register',
                templateUrl: 'auth/_register.html',
                controller: 'AuthCtrl',
                onEnter: ['$state', 'Auth', function($state, Auth) {
                    Auth.currentUser().then(function() {
                        $state.go('home');
                    })
                }]
            });

        $urlRouterProvider.otherwise('home');
    }
]);
// run blocks
app.run(function($rootScope, Auth) {
  // you can inject any instance here
  $rootScope.$on('$stateChangeStart', 
    function(event, toState, toParams, fromState, fromParams){ 
        if(!Auth.isAuthenticated()) {
            // So the magic should probably happen here. But how do I implement this?
            // And how do I allow users to access the /login and /register page?
            event.preventDefault(); 
        }
  })
});

【问题讨论】:

标签: javascript ruby-on-rails angularjs devise angular-ui-router


【解决方案1】:

我写了一篇文章,基本上回答了这个问题(至少在高层次上),名为How to Set Up Authentication with AngularJS and Ruby on Rails

如果您想检查用户是否在任何特定路由上进行了身份验证,您可以(在 Angular 的标准路由器中,虽然我不知道 ui-router)使用resolve。以下是我的一个旧项目中的几条路线:

      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl',
        isPublic: true
      })
      .when('/today', {
        templateUrl: 'views/announcements.html',
        controller: 'AnnouncementsCtrl',
        resolve: {
          auth: ['$auth', function($auth) {
            return $auth.validateUser();
          }]
        }
      })

根路由是公开的,但/today 需要身份验证。也许这也足以让您继续使用 ui-router。旁注:我真的应该更新我的文章来说明 ui-router(或 Angular 的新路由器),因为我认为没有多少人使用常规的旧 Angular 路由器。

编辑:我在另一个项目中记得这件事。这是咖啡脚本。省略不相关的代码。

“使用严格”

angular.module("fooApp", [
  "ngAnimate"
  "ngCookies"
  "ngResource"
  "ngRoute"
  "ngSanitize"
  "ngTouch"
  "ui.router"
  "ng-token-auth"
])
.run ($rootScope, $auth, $location) ->
  $rootScope.$on "auth:login-success", -> $location.path "/"
  $rootScope.$on "auth:logout-success", -> $location.path "/sign-in"
  $rootScope.$on "$stateChangeStart", (event, next) ->
    $auth.validateUser().then (->
      if $location.path() == "/"
        $location.path "/file-uploads"
    ), ->
      if !next.isPublic
        $location.path "/sign-in"

希望那里发生的事情是不言而喻的。从$stateChangeStart 可以看出,这个项目确实使用了 ui-router。

【讨论】:

    猜你喜欢
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2017-05-07
    • 1970-01-01
    • 2014-07-06
    • 2011-06-18
    • 2013-01-25
    相关资源
    最近更新 更多