https://d226lax1qjow5r.cloudfront.net/blog/blogposts/jwts-just-what-are-they/what-are-jwts.png

JWTs: Was sind sie eigentlich?

Zuletzt aktualisiert am September 28, 2023

Lesedauer: 7 Minuten

Einer der Grundsätze, nach denen das Developer Experience Team beim Schreiben von Tutorials vorgeht, ist, dass Sie niemals davon ausgehen, dass die Leute ein technisches Thema kennen. Das ist etwas, was ich oft vergesse und woran ich mich regelmäßig erinnern muss. Wenn Sie jemals das Gefühl haben Gefühl der Schuld auf der anderen Seite dieser Gleichung verspüren, kann ich immer wieder auf dieses immergrüne Venn-Diagramm zurückgreifen:

Venn Diagram crossing what you know vs. what others know in equal mass

Ich habe im Rahmen meiner Arbeit ständig und täglich mit JWTs zu tun, und die Entwicklung unseres PHP-SDK ist eines dieser Themen. Nachdem ich einmal nachgeschaut hatte, wie wir JWTs verwenden, war es das. Aber, mit meinem Prinzip "Niemals Wissen voraussetzen" ist mir klar, dass es eine Menge Leute die keine Ahnung haben, was sie sind. Darüber hinaus haben einige Entwickler mit einer gewissen Erfahrung (sogar in der Erstellung und Nutzung von APIs) noch nie von ihnen gehört oder sie sogar verwendet. Das Tempo der Entwicklung von API-Technologien ist in größeren oder expandierenden Unternehmen viel langsamer als viele denken. Zum Zeitpunkt der Abfassung dieses Artikels schreiben wir das Jahr 2023, und dennoch verwenden viele Banken und pharmazeutische Unternehmen immer noch SOAP.

Bevor wir in die Anatomie von JWTs eintauchen, sollten Sie wissen, dass dieser Artikel Beispiele mit Code enthält. Wenn Sie stattdessen eines unserer Tools zur Erstellung von JWTs verwenden möchten, schauen Sie sich diesem Artikel von Benjamin Aronov der Ihnen zeigt, wie Sie ein JWT vollständig innerhalb des Vonage Dashboards erstellen können.

Die Grundlagen

JWT steht für JSON Web Token. In einem leicht verwirrenden Akronym-Spaghetti-Szenario steht es technisch gesehen für JavaScript Object Notation Web Token in seiner vollständigen Form. Bis zu seiner Einführung in einem Entwurf vom Juli 2011 waren die gängigsten Formen der Authentifizierung für Web-APIs das unverschlüsselte Hinzufügen eines API-Schlüssels und -Geheimnisses in den Query-String einer Anfrage oder die Basisauthentifizierung, bei der ein API-Schlüssel oder ein Geheimnis (oder beides) gehasht werden, in der Regel mit base64-Kodierung und als Header übergeben werden. Ein JWT ist ein Hash, der in der Kopfzeile einer Anfrage enthalten ist (oder auch im Textkörper, aber das ist weniger üblich) und ältere Authentifizierungsmethoden ersetzt.

Bestehende Authentifizierung: Die Nachteile

Warum also die Notwendigkeit einer neuen Authentifizierungstechnik?

Sicherheit

Dies ist wohl der wichtigste Faktor. Die unverschlüsselte Übermittlung eines API-Schlüssels oder -Geheimnisses in der Kopfzeile (oder im Abfrage-String) für jede Anfrage eröffnet einen ziemlich großen Sicherheitsvektor. Es gibt mehr Datenverkehr mit denselben Anmeldeinformationen, die abgefangen werden können, und sobald diese Schlüssel kompromittiert sind, haben Sie Ihre gesamte Anwendung oder Ihren Account geöffnet.

Es gibt eine Falle bei der Basisauthentifizierung - die Art, bei der man {Benutzername}:{Passwort} als String nimmt und ihn mit base64 kodiert. Viele Entwickler, die neu im Bereich der API-Authentifizierung sind, sehen den resultierenden Hash und denken: "Das sieht sicher aus", aber in Wirklichkeit lässt er sich leicht in seine beiden geheimen Teile zerlegen. Gehen Sie zum Beispiel zu https://emn178.github.io/online-tools/base64_decode.html und fügen Sie ein c2VlLXRoYXQtd2FzOmVhc3k=.

Die einzige wirkliche Sicherheitsebene, die Sie bei der Verwendung dieser Methoden schaffen können, ist die Rotation Ihrer Schlüssel. Abhängig von Ihrem API-Produkt haben große Legacy-Codebasen möglicherweise nicht einmal die Möglichkeit, eine Hauptschlüssel/Geheimcode-Kombination zu drehen (insbesondere, wenn sie bei der Kontoerstellung direkt an ein Konto gebunden sind).

Umfang

Bisher wurden bei einfachen Authentifizierungsarten neue Schlüssel zu einem Portfolio hinzugefügt zusätzlich zu Primärschlüsseln hinzugefügt, die Sie normalerweise mit einer Reihe ausgewählter Geltungsbereichen. Dies kann zu einer recht umfangreichen Sammlung von Schlüsseln führen, die für verschiedene Produkte oder spezifische Abfragen verwendet werden - das regelmäßige Rotieren einer großen Anzahl von Schlüsseln kann recht mühsam werden.

Tragbarkeit

Wie beim Geltungsbereich sind auch bei solchen festen Geheimnissen die Berechtigungen der Benutzer, die Geltungsbereiche und der API-Zugang auf dem Server gespeichert. Dadurch sind sie statisch und nicht flexibel, wenn Sie eine komplexere API mit vielen Parametern haben, die beim Empfang einer Anfrage berücksichtigt werden müssen.

Anatomie eines JWT

JWTs zielen darauf ab, alle drei dieser Probleme zu lösen. So sind sie aufgebaut:

Kopfzeilen-Informationen

Wenn wir uns auf den "Header" beziehen, ist es erwähnenswert, dass es sich um den der Header des JWT und nicht ein HTTP-Anfrage-Header ist.

Der Server benötigt Informationen darüber, wie das JWT erstellt wurde. Aufgrund dieser Anforderung enthält der Header Informationen darüber, wie das JWT in zwei Schlüsseln erstellt wurde:

  • alg die in vielen Fällen auf HS256 zurückgehen dürfte

  • typ der das Token als JWT identifiziert (mit der Weiterentwicklung des Standards wird es wahrscheinlich Iterationen oder neue Versionen des Token-Typs geben)

Nutzlast

Die Nutzdaten eines JWT kommen in Form von Forderungendie eine Reihe von Schlüssel-Wert-Paaren sind, die Informationen über das JWT enthalten. Die häufigsten reservierten (oder *Registered Claim Names) sind die folgenden:

  • issdie Quelle des JWT (Anwendung, Organisation usw.)

  • subJWT: ein eindeutiger Wert für den Aussteller, auf den sich die anderen Angaben im Zusammenhang mit dem JWT beziehen

  • expJWT: das Ablaufdatum des JWT

  • iatwann das JWT erstellt wurde (ausgestellt am)

  • jti: ein eindeutiger Bezeichner für dieses JWT

JWTs sind so praktisch für die Authentifizierung, weil Sie ihnen benutzerdefinierte Ansprüche hinzufügen können, die für die Anwendung, die sie verwendet, relevant sind. Nehmen wir zum Beispiel das Vonage JWT - Bei der Verwendung unserer APIs, die JWT-Authentifizierung unterstützen, wird ein benutzerdefinierter Anspruch verwendet, application_id verwendet wird. Vonage kann das JWT mit dem privaten SSH-Schlüssel Ihres Accounts abgleichen (der auf der Seite des Anfrage-Clients verwendet wurde, um das JWT zu generieren), und wenn es gültig ist, kann die Anfrage schnell an die richtige Anwendungsinstanz innerhalb der Vonage APIs weitergeleitet werden.

Wie man ein JWT erstellt: PHP Edition

Als ansässiger PHP-Entwickler in meinem Team werde ich ein gültiges JWT in so wenigen Codezeilen wie möglich generieren, um zu zeigen, wie einfach es ist, damit zu beginnen. Hier ist, was wir brauchen:

  • Eine Anwendungs-ID aus dem Dashboard.

  • Eine Kopie des privaten Schlüssels der Anwendung wurde über das Dashboard heruntergeladen.

Sie können beide in den Einstellungen der Anwendung hier abrufen:

Screenshot of Vonage Dashboard, accessing an Application's Settings

Wir werden dafür den PHP JWT Creator von Vonage auf GitHub verwenden. Um ihn zu installieren, benötigen Sie composer.

composer require vonage/jwt

Und nun der Code:

<?php

require_once "vendor/autoload.php";

$applicationId = "78d335fa-323d-0114-9c3d-d6f0d48968cf";
$privateKey = file_get_contents('private.key');
$generator = new Vonage\JWT\TokenGenerator($applicationId, $privateKey);
$jwt = $generator->generate();

Erledigt!

Um dies in einer Anfrage zu verwenden, müssen Sie es als Kopfzeile hinzufügen. Wir benötigen eine PSR-18-kompatiblen HTTP-Client, um ihn zu senden. Ich habe mich für den HTTPClient von Symfony entschieden, um zu zeigen, wie wenige Zeilen wir brauchen, um das zu tun. Um diese zu installieren, fügen Sie sie mit Composer zu Ihrem Projekt hinzu:

composer require symfony/http-client

Und dann werden wir eine Anfrage an die POST Vonage Messages API unter Verwendung unseres JWT:

use Symfony\Component\HttpClient\HttpClient;

$payload = [
	'message_type' => 'text',
	'text' => 'Using a JWT to send Vonage a request!',
	'to' => '44779999999',
	'from' => '44779499999',
	'channel' => 'sms'
]

$client = HttpClient::create();

$client->request('POST', 'https://api.nexmo.com/v1/messages/', [
	'headers' => [
		'Authorization' => 'Bearer ' . $jwt,
		'Content-Type' => 'application/json',
	],
	'json' => $payload
])

Und da haben Sie es! Natürlich ist dies nur ein grobes Beispiel dafür, wie man es macht. Wenn Sie eine vollständige Integration wünschen, empfehle ich Ihnen, unser Core PHP SDK zu verwenden, das Ihnen viele Kopfschmerzen erspart. Wenn PHP nicht Ihre bevorzugte Sprache ist, ist das kein Problem! Wir haben auch SDKs für Node, Java, Python, Ruby und NET!

Teilen Sie:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondeSenior PHP Entwickler Advocate

Als ausgebildeter Schauspieler mit einer Dissertation in Standup-Comedy bin ich über die Meetup-Szene zur PHP-Entwicklung gekommen. Man findet mich, wenn ich über Technik spreche oder schreibe, oder wenn ich seltsame Platten aus meiner Vinylsammlung spiele oder kaufe.