如何使用AngularFire实现基于角色的访问控制 [英] How to implement a role based access control with AngularFire

查看:197
本文介绍了如何使用AngularFire实现基于角色的访问控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的理解是我需要执行以下步骤:

My understanding is that I need to undertake the following steps:


  • 将用户角色设为只读

  • 对访问角色以控制访问的数据使用安全规则

  • 检查路由器中的角色

官方文档中有各种关于如何处理安全规则的例子,但我无法弄清楚如何检查路由器中的角色。我们假设我有一个仅限管理员的区域,如果非管理员的某个人试图访问该页面,我希望该用户被重定向。

There are various examples on the official documentation how to deal with the security rules, but I couldn't figure out how to check for the role in the router. Let's assume I have an admin-only area, if someone who is not an admin tries to access that page I want that user to be redirected.

我正在关注使用UI-Router的官方示例,这是我的代码:

I'm currently following the official example using UI-Router, so this is my code:

app.config(["$stateProvider", function ($stateProvider) {
$stateProvider
.state("home", {
  // the rest is the same for ui-router and ngRoute...
  controller: "HomeCtrl",
  templateUrl: "views/home.html",
  resolve: {
    // controller will not be loaded until $waitForSignIn resolves
    // Auth refers to our $firebaseAuth wrapper in the factory below
    "currentAuth": ["Auth", function(Auth) {
      // $waitForSignIn returns a promise so the resolve waits for it to complete
      return Auth.$waitForSignIn();
    }]
  }
})
.state("account", {
  // the rest is the same for ui-router and ngRoute...
  controller: "AccountCtrl",
  templateUrl: "views/account.html",
  resolve: {
    // controller will not be loaded until $requireSignIn resolves
    // Auth refers to our $firebaseAuth wrapper in the factory below
    "currentAuth": ["Auth", function(Auth) {
      // $requireSignIn returns a promise so the resolve waits for it to complete
      // If the promise is rejected, it will throw a $stateChangeError (see above)
      return Auth.$requireSignIn();
    }]
  }
});
}]);

我猜我必须检查用户角色的决心,但是怎么会我从那里访问数据库中的数据?

I'm guessing I'll have to check in the resolve for a user role, but how would I access the data from the database there?

更新:

我试过André的解决方案,但waitForAuth(console.log(test1)永远不会触发。waitForSignIn虽然有,但没有任何反应 - 没有错误消息。

I tried André's solution, but "waitForAuth" (console.log("test1") never triggers. "waitForSignIn" does though, but then nothing happens - there is no error message.

.state('superadmin-login', {
    url: '/superadmin',
    templateUrl: 'views/superadmin-login.html',
    'waitForAuth': ['Auth', function (Auth) {
        console.log('test1');
        // $requireAuth returns a promise so the resolve waits for it to complete
        // If the promise is rejected, it will throw a $stateChangeError (see above)
        return Auth.refAuth().$waitForSignIn();
    }],
})
.state('superadmin', {
    url: '/center-of-the-universe',
    templateUrl: 'views/superadmin.html',
    resolve: {
        // YOUR RESOLVES GO HERE
        // controller will not be loaded until $requireAuth resolves
        // Auth refers to our $firebaseAuth wrapper in the example above
        'currentAuth': ['Auth', function (Auth) {
            console.log('test2');
            // $requireAuth returns a promise so the resolve waits for it to complete
            // If the promise is rejected, it will throw a $stateChangeError (see above)
            return Auth.refAuth().$requireSignIn();
        }],
        //Here i check if a user has admin rights, note that i pass currentAuth and waitForAuth to this function to make sure those are resolves before this function
        hasAdminAccess: function (currentAuth, waitForAuth, Rights) {
            console.log('test');
            return Rights.hasAdminAccess(currentAuth);
        }
    }
})


推荐答案

以下是我的表现。

首先我做了一个工厂来检查用户是否拥有正确的权利:

First i made a factory to check if the user has the correct rights:

angular.module('rights.services', [])
.factory('Rights', function ($q) {
    var ref = firebase.database().ref();

    return {
        hasAdminAccess: function (user) {
            var deferred = $q.defer();
            ref.child("Rights").child("Admin").child(user.uid).once('value').then(function (snapshot) {
                if (snapshot.val()) {
                    deferred.resolve(true);
                }
                else{
                    deferred.reject("NO_ADMIN_ACCESS");
                }
            });
            return deferred.promise;
        }
    };
});

其次我在决议中使用这个工厂:

And secondly i use this factory inside the resolve:

.state('logged', {
            url: '',
            abstract: true,
            templateUrl: helper.basepath('app.html'),
            resolve: {
                    // YOUR RESOLVES GO HERE
                    // controller will not be loaded until $requireAuth resolves
                    // Auth refers to our $firebaseAuth wrapper in the example above
                    "currentAuth": ["Auth", function (Auth) {
                        // $requireAuth returns a promise so the resolve waits for it to complete
                        // If the promise is rejected, it will throw a $stateChangeError (see above)
                        return Auth.refAuth().$requireSignIn();
                    }],
                    "waitForAuth": ["Auth", function (Auth) {
                        // $requireAuth returns a promise so the resolve waits for it to complete
                        // If the promise is rejected, it will throw a $stateChangeError (see above)
                        return Auth.refAuth().$waitForSignIn();
                    }],
                    //Here i check if a user has admin rights, note that i pass currentAuth and waitForAuth to this function to make sure those are resolves before this function
                    hasAdminAccess: function (currentAuth, waitForAuth, Rights) {
                        return Rights.hasLightAccess(currentAuth);
                    }
                })
        })

请记住在firebase中保存用户角色的方式可能与我在此示例中的方式不同。这是(部分)它在firebase中的样子:

Keep in mind the way you save user roles in firebase can be different from how i do it in this example. This is (part of) how it looks in firebase:

{"moderators": 
  {
  "0123eeca-ee0e-4ff1-9d13-43b8914999a9" : true,
  "3ce9a153-eea8-498f-afad-ea2a92d79950" : true,
  "571fa880-102d-4372-be8d-328ed9e7c9de" : true
  }
},
{"Admins": 
  {
  "d3d4effe-318a-43e1-a7b6-d7faf3f360eb" : true
  }
}

以及这些节点的安全规则:

And the security rules for these nodes:

"Admins": {
    "$uid": {
      //No write rule so admins can only be added inside the firebase console
      ".read": "auth != null && auth.uid ==$uid"
    }
},
"Moderators" : {
  //Admins are able to see who the moderators are and add/delete them
  ".read" : "(auth != null) && (root.child('Admins').hasChild(auth.uid))",
  ".write" : "(auth != null) && (root.child('Admins').hasChild(auth.uid))",
    "$uid": {
      ".read": "auth != null && auth.uid ==$uid"
    }
}

这篇关于如何使用AngularFire实现基于角色的访问控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆