Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/425.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用AngularFire实现基于角色的访问控制_Javascript_Firebase_Angularfire_Firebase Authentication_Firebase Security - Fatal编程技术网

Javascript 如何使用AngularFire实现基于角色的访问控制

Javascript 如何使用AngularFire实现基于角色的访问控制,javascript,firebase,angularfire,firebase-authentication,firebase-security,Javascript,Firebase,Angularfire,Firebase Authentication,Firebase Security,我的理解是,我需要采取以下步骤: 将用户角色设置为只读 对访问角色的数据使用安全规则来控制访问 检查路由器中的角色 官方文档中有很多关于如何处理安全规则的例子,但我不知道如何检查路由器中的角色。让我们假设我有一个管理员专区,如果有人不是管理员试图访问该页面,我希望该用户被重定向 我目前正在遵循,因此这是我的代码: app.config(["$stateProvider", function ($stateProvider) { $stateProvider .state("home", {

我的理解是,我需要采取以下步骤:

将用户角色设置为只读 对访问角色的数据使用安全规则来控制访问 检查路由器中的角色 官方文档中有很多关于如何处理安全规则的例子,但我不知道如何检查路由器中的角色。让我们假设我有一个管理员专区,如果有人不是管理员试图访问该页面,我希望该用户被重定向

我目前正在遵循,因此这是我的代码:

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();
    }]
  }
});
}]);
我猜我必须签入用户角色的解析,但是如何从那里的数据库访问数据呢

更新:

我尝试了安德烈的解决方案,但waitForAuth console.logtest1从未触发。waitForSignIn虽然这样做了,但是什么也没有发生——没有错误消息

.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);
        }
    }
})
我是这样做的

首先,我制作了一个工厂来检查用户是否拥有正确的权限:

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;
        }
    };
});
其次,我在解决方案中使用了这个工厂:

.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中的部分外观:

{"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
  }
}
以及这些节点的安全规则:

"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"
    }
}
我是这样做的

首先,我制作了一个工厂来检查用户是否拥有正确的权限:

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;
        }
    };
});
其次,我在解决方案中使用了这个工厂:

.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中的部分外观:

{"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
  }
}
以及这些节点的安全规则:

"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"
    }
}

回答得好,安德烈。能否添加用于权限的JSON结构的片段?还有可能是安全规则,因为这是确保您的规则得到执行的唯一方法?非常感谢您的帮助André,我非常感谢。请参阅上面我的更新-我不确定我是否实现了错误的解决方案,因为我没有使用抽象状态?@user3255061它与抽象状态无关,但与您的waitForAuth处于不同状态这一事实有关。您还可以将其置于其他状态,或从hasAdminAccess函数中将其删除。那么它应该会起作用。@AndréKool喜欢这样:?那不行。还是我误解了你?非常感谢你的帮助。回答得很好,安德烈。能否添加用于权限的JSON结构的片段?还有可能是安全规则,因为这是确保您的规则得到执行的唯一方法?非常感谢您的帮助André,我非常感谢。请参阅上面我的更新-我不确定我是否实现了错误的解决方案,因为我没有使用抽象状态?@user3255061它与抽象状态无关,但与您的waitForAuth处于不同状态这一事实有关。您还可以将其置于其他状态,或从hasAdminAccess函数中将其删除。那么它应该会起作用。@AndréKool喜欢这样:?那不行。还是我误解了你?非常感谢你的帮助。