1

Mein Verständnis zu implementieren ist, dass ich die folgenden Schritte unternehmen müssen:Wie eine rollenbasierte Zugriffskontrolle mit AngularFire

  • die Rollen schreibgeschützt auf dem Daten
  • Verwenden Sicherheitsregeln der Nutzer machen, die Zugang die Rollen Zugriff auf den Router
  • prüfen für die Rolle steuern

Es gibt verschiedene Beispiele auf der offiziellen Dokumentation, wie mit den Sicherheitsregeln umgehen, aber ich konnte nicht herausfinden, ho w nach der Rolle im Router suchen. Nehmen wir an, ich habe einen Admin-Bereich. Wenn jemand, der kein Administrator ist, versucht, auf diese Seite zuzugreifen, möchte ich, dass dieser Benutzer umgeleitet wird.

Ich verfolge derzeit die official example using UI-Router, so ist dies mein 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(); 
    }] 
    } 
}); 
}]); 

Ich vermute, ich werde für eine Benutzerrolle in der Entschlossenheit überprüfen müssen, aber wie würde ich auf die Daten zugreifen von der Datenbank dort?

Update:

Ich versuchte André-Lösung, aber "waitForAuth" (console.log ("test1") löst nie "waitForSignIn" tut zwar, aber dann passiert nichts - es gibt keine Fehlermeldung..

.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); 
     } 
    } 
}) 

Antwort

3

Hier ist, wie ich es tat

Zuerst habe ich eine Fabrik zu überprüfen, ob der Benutzer die richtigen Rechte hat.

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; 
     } 
    }; 
}); 

Und zweitens benutze ich diese Fabrik in der Entschlossenheit:

.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); 
        } 
       }) 
     }) 

Beachten Sie, wie Sie Benutzerrollen in Feuerbasis speichern kann anders sein, wie ich es in diesem Beispiel zu tun. Dies ist (Teil), wie es aussieht in Feuerbasis:

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

Und die Sicherheitsregeln für diese Knoten:

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

Große Antwort Andre. Können Sie ein Snippet der JSON-Struktur hinzufügen, die Sie für die Berechtigungen verwenden? Und möglicherweise auch die Sicherheitsregeln (denn nur so können Sie sicher sein, dass Ihre Regeln durchgesetzt werden). –

+0

Vielen Dank für Ihre Hilfe André, ich schätze es sehr. Bitte beachten Sie mein Update oben - ich bin mir nicht sicher, ob ich Ihre Lösungen falsch implementiere, weil ich keine abstrakten Zustände verwende? – user3255061

+0

@ user3255061Es hat nichts mit dem abstrakten Zustand zu tun, sondern mit der Tatsache, dass Sie waitForAuth in einem anderen Zustand haben. Sie können es auch in den anderen Status versetzen oder aus der Funktion hasAdminAccess entfernen. Dann sollte es funktionieren. –