Wie man eine REST API mit Symfony und JWT-Authentifizierung aufbaut
In diesem Tutorial zeige ich dir Schritt für Schritt, wie du eine REST API mit dem Symfony Framework erstellst. Diese API wird durch ein Token-basiertes Authentifizierungssystem abgesichert, sodass nur autorisierte Benutzer darauf zugreifen können.
Voraussetzungen
- Grundkenntnisse in PHP und Composer.
- PHP 8.2 oder höher.
- Composer (der PHP-Paketmanager).
- Ein grundlegendes Verständnis von Symfony und RESTful APIs ist von Vorteil, aber nicht zwingend notwendig.
1. Symfony installieren
Zuerst müssen wir Symfony installieren. Öffne dein Terminal und führe folgenden Befehl aus:
composer create-project symfony/skeleton my_rest_api
Dieser Befehl erstellt ein neues Symfony-Projekt in einem Ordner namens my_rest_api
. Der Symfony-Skeleton ist ein minimales Grundgerüst, ideal für den Aufbau einer API.
Wechsle in dein neu erstelltes Projektverzeichnis:
cd my_rest_api
2. API-Bundle installieren
Das API Platform Bundle von Symfony erleichtert es, APIs zu erstellen. Um es zu installieren, führen wir den folgenden Befehl aus:
composer require api
Dadurch wird die API Platform in deinem Symfony-Projekt aktiviert. Mit diesem Bundle hast du bereits viele hilfreiche Funktionen, wie automatische Dokumentation. (Hinweis: Docker kannst du je nach belieben installieren oder weglassen. Ich gehe erstmal nicht weiter auf Docker in diesem Tutorial ein.)
3. Ein Datenbankmodell erstellen
Wir erstellen nun eine einfache Entity, um unsere API aufzubauen. Eine Entity ist im Wesentlichen eine Klasse, die in der Datenbank gespeichert wird.
Zuerst müssen wir sicherstellen, dass du eine Datenbank konfiguriert hast. Dupliziere hierzu die .env
Datei und benenne diese wie folgt .env.local – hinterlege deine Datenbank Einstellungen:
DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=8&charset=utf8mb4"
Erstelle die Datenbank mit:
php bin/console doctrine:database:create
Um eine Entity zu erstellen, verwenden wir im Anschluss den Befehl folgende zwei Befehle:
composer require symfony/maker-bundle --dev
php bin/console make:entity
Nennen wir die Entity zum Beispiel Product
. Du wirst nun gefragt, welche Felder die Entity haben soll. Fügen wir zwei einfache Felder hinzu:
name
(string)price
(float)
Jetzt wird die Datei src/Entity/Product.php
generiert.
Damit die Entity in der Datenbank angelegt wird, führen wir folgende Befehle aus:
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Der erste Befehl erstellt die Datenbank, der zweite erstellt eine Migrationsdatei, und der letzte führt diese Migration aus, um die Tabelle in der Datenbank anzulegen.
4. Die API-Ressource freigeben
Jetzt machen wir diese Product-Entity über unsere API zugänglich. Dafür markieren wir die Product
-Entity als API-Resource, indem wir die folgende Annotation hinzufügen:
// src/Entity/Product.php
use App\Repository\ProductRepository;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Metadata\ApiResource;
#[ApiResource]
#[ORM\Entity(repositoryClass: ProductRepository::class)]
class Product
{
// ...
}
API Platform wird automatisch CRUD-Operationen (Create, Read, Update, Delete) für diese Ressource freigeben. Wenn du nun http://localhost/my_rest_api/public/index.php/api
besuchst, siehst du die neue Ressource Product
.
5. Authentifizierung mit JWT einrichten
Nun sichern wir die API mit JWT ab, sodass nur authentifizierte Benutzer Zugriff haben. Dazu verwenden wir das LexikJWTAuthenticationBundle. Installiere es mit folgendem Befehl:
composer require lexik/jwt-authentication-bundle:^2.19
Dieses Bundle hilft uns dabei, JSON Web Tokens zu generieren und zu validieren.
a) Konfiguration des JWT-Bundles
Wir müssen nun einige Schritte durchführen, um JWT korrekt zu konfigurieren. Zuerst generieren wir ein Schlüsselpaar für die Token-Signierung:
php bin/console lexik:jwt:generate-keypair
Dies erstellt zwei Dateien (private.pem
und public.pem
), die für die Signierung und Validierung der JWTs verwendet werden.
Jetzt müssen wir das Security-System von Symfony konfigurieren. Öffne die Datei config/packages/security.yaml
und füge den folgenden Code hinzu:
security:
encoders:
Symfony\Component\Security\Core\User\UserInterface:
algorithm: auto
providers:
app_user_provider:
entity:
class: App\Entity\User
property: email
firewalls:
login:
pattern: ^/api/login
stateless: true
json_login:
check_path: /api/login
username_path: email
password_path: password
api:
pattern: ^/api
stateless: true
jwt: ~
provider: app_user_provider
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
b) Ein User-Entity erstellen
Wir benötigen eine User-Entity, um Benutzer zu verwalten. Erstelle diese Entity mit folgendem Befehl:
php bin/console make:user
Folge den Anweisungen und füge Felder wie email
und password
hinzu. Anschließend führe die Migrationsschritte durch, um die User
-Tabelle zu erstellen:
php bin/console make:migration
php bin/console doctrine:migrations:migrate
6. Registrierung und Login einrichten
a) Registrierung
Erstelle einen Controller für die Registrierung:
php bin/console make:controller RegistrationController
Füge in der RegistrationController.php
eine Methode hinzu, um neue Benutzer zu registrieren:
// src/Controller/RegistrationController.php
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use App\Entity\User;
class RegistrationController
{
#[Route('/api/register', methods: ['POST'])]
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder): Response
{
$data = json_decode($request->getContent(), true);
$user = new User();
$user->setEmail($data['email']);
$user->setPassword($passwordEncoder->encodePassword($user, $data['password']));
// Speichere den Benutzer in der Datenbank...
return new Response('User registered successfully!', Response::HTTP_CREATED);
}
}
b) Login
Der Login wird über die in security.yaml
konfigurierte Route /api/login
abgewickelt. Um dich anzumelden, sende eine POST-Anfrage mit den Anmeldedaten (email
, password
) an diese Route, und bei Erfolg erhältst du ein JWT-Token zurück.
7. API-Zugriff testen
Jetzt kannst du deine API mit einem Tool wie Postman, SOAP Ui oder cURL testen. Sende eine POST-Anfrage an /api/login
mit den Benutzerdaten, und du erhältst ein JWT-Token zurück, das du in den folgenden Anfragen als Authorization-Header senden musst:
Authorization: Bearer <dein_token>
Fazit
Herzlichen Glückwunsch! Du hast eine funktionierende REST API mit Symfony erstellt und die Authentifizierung über JWT integriert. Von hier aus kannst du die API weiter ausbauen, zusätzliche Ressourcen hinzufügen oder tiefer in Symfony und die API Platform eintauchen.
Weitere Beiträge
TYPO3 | Checkbox in Extbase Extension
Eigenes Inhaltselement für TYPO3 7.6.x - 9.5.x
TYPO3 Backend Editor in eigener Extension nutzen
CSS3 Animation mit CSS Transitions