Schlüsselpunkte
Authentifizierung und Autorisierung sind ein wichtiger Bestandteil fast jeder ernsthaften Anwendung. Einzelseiten -Anwendungen (SPAs) sind keine Ausnahme. Die Anwendung darf keinen alle Daten und Funktionen einem Benutzer vorstellen. Benutzer müssen sich möglicherweise authentifizieren, um bestimmte Teile der Anwendung anzuzeigen oder bestimmte Aktionen für die Anwendung auszuführen. Um Benutzer in der Anwendung zu identifizieren, müssen wir uns anmelden.
In herkömmlichen servergesteuerten Anwendungen und Einzel-Seiten-Anwendungen ist die Implementierung der Benutzerverwaltung unterschiedlich. Ein Spa interagiert nur mit seinen Serverkomponenten über Ajax. Dies gilt auch für Anmeldung und Abmelden.
Der Server, der für die Identifizierung von Benutzern verantwortlich ist, muss den Authentifizierungsendpunkt freilegen. Das Spa sendet die von den benutzergerichteten Anmeldeinformationen zur Überprüfung an diesen Endpunkt. In einem typischen tokenbasierten Authentifizierungssystem kann ein Dienst nach Überprüfung der Anmeldeinformationen ein Service ein Zugriffstoken oder ein Objekt zurückgeben, das den Namen und die Rolle des protokollierten Benutzers enthält. Der Client muss dieses Zugriffstoken in allen sicheren API -Anforderungen an den Server verwenden.
Da das Zugangs -Token mehrmals verwendet wird, speichern Sie es am besten auf dem Kunden. In Angular können wir Werte in einem Dienst oder in Werten speichern, da es sich um Singleton -Objekte auf dem Kunden handelt. Wenn der Benutzer die Seite jedoch aktualisiert, geht der Wert im Dienst oder Wert verloren. In diesem Fall ist es am besten, einen der vom Browser bereitgestellten Persistenzmechanismen zu verwenden, um das Token zu speichern.
Anmeldungerreichen Schauen wir uns jetzt einen Code an. Angenommen, wir haben alle serverseitigen Logik implementiert, und der Dienst enthält einen REST-Endpunkt bei /API /Login, um Anmeldeinformationen zu überprüfen und das Zugriffs-Token zurückzugeben. Schreiben wir einen einfachen Dienst, der Anmeldevorgänge ausführt, indem wir auf den Authentifizierungsendpunkt zugreifen. Wir werden diesem Service später weitere Funktionen hinzufügen:
app.factory("authenticationSvc", function($http, $q, $window) { var userInfo; function login(userName, password) { var deferred = $q.defer(); $http.post("/api/login", { userName: userName, password: password }).then(function(result) { userInfo = { accessToken: result.data.access_token, userName: result.data.userName }; $window.sessionStorage["userInfo"] = JSON.stringify(userInfo); deferred.resolve(userInfo); }, function(error) { deferred.reject(error); }); return deferred.promise; } return { login: login }; });
In dem tatsächlichen Code möchten Sie möglicherweise die Anweisungen, die Daten in SessionStorage in einen separaten Dienst speichern, neu gestalten, da dieser Dienst, wenn wir dies tun, mehrere Verantwortlichkeiten übernimmt. Um die Demo einfach zu halten, behalte ich sie im selben Service. Dieser Dienst kann von einem Controller verwendet werden, der die Anwendungsanmeldungsfunktion übernimmt.
Schutz der Route
wir können in unserer Anwendung eine Reihe von geschützten Routen haben. Wenn der Benutzer nicht angemeldet ist und versucht, eine dieser Routen einzugeben, sollte der Benutzer auf die Anmeldeseite gerichtet werden. Dies kann mit dem Resolve -Block in den Routing -Optionen erfolgen. Der folgende Code -Snippet zeigt die Implementierung:
$routeProvider.when("/", { templateUrl: "templates/home.html", controller: "HomeController", resolve: { auth: ["$q", "authenticationSvc", function($q, authenticationSvc) { var userInfo = authenticationSvc.getUserInfo(); if (userInfo) { return $q.when(userInfo); } else { return $q.reject({ authenticated: false }); } }] } });
Resolve kann mehrere Anweisungsblöcke enthalten, die nach Abschluss ein Versprechensobjekt zurückgeben müssen. Nur um zu verdeutlichen, wird der oben definierte Name nicht durch den Framework definiert. Sie können den Namen basierend auf dem Anwendungsfall in einen beliebigen Namen ändern.
Es gibt mehrere Gründe, die dazu führen können, dass das Routing verabschiedet oder abgelehnt wird. Abhängig vom Szenario können Sie Objekte übergeben, wenn Sie Versprechen analysieren/ablehnen. Wir haben die Methode getLoggedInuser () im Dienst nicht implementiert. Dies ist eine einfache Möglichkeit, ein ProtokolledInuser -Objekt aus dem Dienst zurückzugeben.
app.factory("authenticationSvc", function() { var userInfo; function getUserInfo() { return userInfo; } });
Das von Versprechen im obigen Code -Snippet gesendete Objekt wird über $ rootscope ausgestrahlt. Wenn die Route gelöst wurde, wird die Veranstaltung $ routechangesuccess ausgestrahlt. Wenn das Routing jedoch fehlschlägt, wird das Ereignis $ routechangeError ausgestrahlt. Wir können das Ereignis $ routechangeError anhören und den Benutzer auf die Anmeldeseite umleiten. Da die Ereignisse auf der Ebene $ Rootscope liegen, ist es am besten, einen Event -Handler im Laufblock zu fügen.
app.run(["$rootScope", "$location", function($rootScope, $location) { $rootScope.$on("$routeChangeSuccess", function(userInfo) { console.log(userInfo); }); $rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) { if (eventObj.authenticated === false) { $location.path("/login"); } }); }]);
Verarbeitungsseite Aktualisieren
Wenn ein Benutzer auf die Aktualisierungsschaltfläche der Seite klickt, verliert der Dienst seinen Status. Wir müssen die Daten aus dem SessionStorage des Browsers abrufen und sie dem VariablenprotokolledInuser zuweisen. Da die Fabrik nur einmal aufgerufen wird, können wir diese Variable in der Initialisierungsfunktion wie unten gezeigt einstellen.
function init() { if ($window.sessionStorage["userInfo"]) { userInfo = JSON.parse($window.sessionStorage["userInfo"]); } } init();
abbrechen
Wenn sich der Benutzer aus der Anwendung abzeichnet, muss die entsprechende API aufgerufen und das Zugangs -Token im Anforderungsheader enthalten sein. Nachdem sich der Benutzer angemeldet hat, sollten wir die Daten auch in SessionStorage löschen. Das folgende Beispiel enthält die Abmeldefunktion, die dem Authentifizierungsdienst hinzugefügt werden muss.
function logout() { var deferred = $q.defer(); $http({ method: "POST", url: logoutUrl, headers: { "access_token": userInfo.accessToken } }).then(function(result) { $window.sessionStorage["userInfo"] = null; userInfo = null; deferred.resolve(result); }, function(error) { deferred.reject(error); }); return deferred.promise; }
Schlussfolgerung
Die Methode zur Implementierung der Authentifizierung in einer einzelnen Seitenanwendung unterscheidet sich stark von der der herkömmlichen Webanwendungen. Da der größte Teil der Arbeit am Client erledigt ist, muss der Status des Benutzers auch irgendwo auf dem Client gespeichert werden. Es ist wichtig zu beachten, dass der Staat auch auf der Serverseite gepflegt und verifiziert werden muss, da Hacker möglicherweise Daten stehlen, die auf das Client -System gespeichert sind.
Der Quellcode in diesem Artikel kann auf GitHub heruntergeladen werden.
FAQs zur Implementierung der Authentifizierung in Winkelanwendungen
withcredentials wird verwendet, um Authentifizierungs -Cookies in HTTP -Anfragen aufzunehmen. In Angular können Sie es im HTTPClient -Modul verwenden. Bei einer Anfrage können Sie die Withcredentials -Eigenschaft auf true einstellen. Hier ist ein Beispiel:
this.http.get(url, { withCredentials: true }).subscribe(...);
Dies enthält Cookies, die möglicherweise vor dem Server gesendet wurden.
httpinterceptor ist eine Funktion in Angular, mit der Sie HTTP -Anforderungen global abfangen und ändern können, bevor Sie sie an den Server senden. Es ist sehr nützlich für verschiedene Aufgaben, z. B. für das Hinzufügen eines Authentifizierungs -Tokens zu allen Anfragen oder zur Behandlung globaler Fehler.
Um einen benutzerdefinierten httpinterceptor zu erstellen, müssen Sie einen Dienst erstellen, der die HTTPInterceptor -Schnittstelle implementiert. Hier ist ein Beispiel:
app.factory("authenticationSvc", function($http, $q, $window) { var userInfo; function login(userName, password) { var deferred = $q.defer(); $http.post("/api/login", { userName: userName, password: password }).then(function(result) { userInfo = { accessToken: result.data.access_token, userName: result.data.userName }; $window.sessionStorage["userInfo"] = JSON.stringify(userInfo); deferred.resolve(userInfo); }, function(error) { deferred.reject(error); }); return deferred.promise; } return { login: login }; });
Diese Interceptor klone jede Anfrage und legt die Eigenschaft mit dem Verringungszusammenhang auf true fest.
cors (Cross-Original-Ressourcenfreigabe) ist eine Sicherheitsfunktion, die die Art und Weise einschränkt, in der die Ressourcen in allen Domänen geteilt werden. Wenn Sie einen CORS -Fehler erhalten, ist der Server nicht so konfiguriert, dass Sie Anforderungen Ihrer Domäne annehmen. Um dies zu beheben, müssen Sie den Server so konfigurieren, dass Sie Ihre Domäne in den Header "Access-Control-Allow-Origin" einbeziehen und "Access-Control-Allow-Credentials" auf True festlegen.
Die Eigenschaft mit XMLHTTPrequest -Withcredentials funktioniert ähnlich wie bei der Eigenschaft anwinkeler Httpclient. Es wird verwendet, um Cookies in die Anfrage aufzunehmen. Hier ist ein Beispiel:
$routeProvider.when("/", { templateUrl: "templates/home.html", controller: "HomeController", resolve: { auth: ["$q", "authenticationSvc", function($q, authenticationSvc) { var userInfo = authenticationSvc.getUserInfo(); if (userInfo) { return $q.when(userInfo); } else { return $q.reject({ authenticated: false }); } }] } });
sendet eine GET -Anforderung mit dem Cookie an die angegebene URL.
Die verbleibenden FAQs beziehen sich auf die Verwendung von httpclientModule und haben wenig mit dem Kernthema des Artikels (der Authentifizierungsimplementierung in Angular) zu tun, sodass sie hier weggelassen werden. Diese Fragen können leicht durch Suchmaschinen gefunden werden.
Das obige ist der detaillierte Inhalt vonImplementierung der Authentifizierung in Winkelanwendungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!