
In diesem Lernprogramm werden wir kurz untersuchen, wie REST-Anforderungen an die API implementiert werden, für die der Benutzer autorisiert werden muss, und einen asynchronen „Wrapper“ für die Anforderung erstellen, der die Autorisierung überprüft und rechtzeitig aktualisiert.
Anmeldeinformationen
Nachdem wir eine REST-Anfrage an die API gestellt haben, wo wir den Login und das Passwort gesendet haben, erhalten wir im Gegenzug json des folgenden Formats (die Werte sind zufällig und die Zeilen sind normalerweise länger):
{ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSld", "refresh_token": "1eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgS", "expires_in": 124234149563 }
Die Antwort enthält möglicherweise mehr
Felder , z. B.
"token_type" ,
"expires_on" usw. Für diese Implementierung benötigen wir jedoch nur die drei oben genannten Felder.
Schauen wir sie uns genauer an:
- access_token - das Token, das wir im Header jeder Anforderung senden müssen, um Daten als Antwort zu erhalten
- refresh_token - das Token, das wir senden müssen, um ein neues Token zu erhalten, wenn das alte abläuft
- expires_in - Token-Lebensdauer in Sekunden
Token empfangen
Erstellen Sie nun eine Funktion, die den oben beschriebenen JSON empfängt, und speichern Sie ihn.
Wir speichern Daten zur Autorisierung je nach Bedarf in
sessionStorage oder
localStorage . Im ersten Fall werden die Daten gespeichert, bis der Benutzer die Sitzung beendet oder den Browser schließt. Im zweiten Fall werden die Daten unbegrenzt im Browser gespeichert, bis der localStorage aus irgendeinem Grund gelöscht wird.
Funktion zum Speichern des Tokens in sessionStorage:
function saveToken(token) { sessionStorage.setItem('tokenData', JSON.stringify(token)); }
Funktion zum Empfangen eines Tokens:
function getTokenData(login, password) { return fetch('api/auth', { method: 'POST', credentials: 'include', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ login, password, }), }) .then((res) => { if (res.status === 200) { const tokenData = res.json(); saveToken(JSON.stringify(tokenData));
Daher haben wir ein Token mit den Feldern
"access_token" ,
"refresh_token" und
"expires_in" erhalten und zur weiteren Verwendung in
sessionStorage gespeichert.
Token-Update
Das Token, das wir zuvor erhalten haben, hat eine begrenzte Lebensdauer, die im Feld
"expires_in" festgelegt ist. Nach Ablauf seiner Lebensdauer kann der Benutzer keine neuen Daten empfangen, indem er dieses Token in der Anforderung sendet. Daher müssen Sie ein neues Token erhalten.
Wir können das Token auf zwei Arten erhalten: Die erste Möglichkeit besteht darin, sich erneut anzumelden, indem Sie den Benutzernamen und das Kennwort an den Server senden. Dies passt jedoch nicht zu uns, da es falsch ist, den Benutzer zu zwingen, die Berechtigungsdaten jedes Mal nach einem bestimmten Zeitraum erneut einzugeben - dies sollte automatisch erfolgen. Das Speichern eines Login / Passwort-Paares irgendwo im Speicher für das automatische Senden ist jedoch unsicher. Deshalb benötigen wir ein
refresh_token , das zuvor mit
access_token empfangen und in sessionStorage gespeichert wurde. Durch Senden dieses Tokens an eine andere von der API bereitgestellte Adresse können wir als Antwort ein neues "frisches" Token erhalten.
Funktion für Token Update
function refreshToken(token) { return fetch('api/auth/refreshToken', { method: 'POST', credentials: 'include', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ token, }), }) .then((res) => { if (res.status === 200) { const tokenData = res.json(); saveToken(JSON.stringify(tokenData));
Mit dem obigen Code haben wir das Token in sessionStorage neu geschrieben und können nun auf neue Weise Anforderungen an die API senden.
Erstellen einer Wrapper-Funktion
Jetzt erstellen wir eine Funktion, die dem Anforderungsheader Berechtigungsdaten hinzufügt und diese bei Bedarf automatisch aktualisiert, bevor die Anforderung gestellt wird.
Wenn das Token abgelaufen ist und wir ein neues Token anfordern müssen, ist unsere Funktion asynchron. Dazu verwenden wir das Konstrukt async / await.
Wrapper-Funktion
export async function fetchWithAuth(url, options) { const loginUrl = '/login';
Mit dem obigen Code haben wir eine Funktion erstellt, die Anforderungen in der API ein Token hinzufügt. Mit dieser Funktion können wir das Abrufen in den benötigten Abfragen ersetzen, wenn eine Autorisierung erforderlich ist, und dafür müssen wir die Syntax nicht ändern oder den Argumenten keine weiteren Daten hinzufügen.
Es reicht gerade aus, es in eine Datei zu „importieren“ und den Standardabruf dadurch zu ersetzen.
import fetchWithAuth from './api'; function getData() { return fetchWithAuth('api/data', options) }