Dieser Artikel bietet eine umfassende Schritt-für-Schritt-Anleitung zur Implementierung von Authentifizierung und Autorisierung in einer NestJS-Backend-Anwendung mit Clerk.
Clerk ist eine umfassende Plattform, die einbettbare Benutzeroberflächen, flexible APIs und ein intuitives und robustes Dashboard für eine nahtlose Benutzerauthentifizierung und -verwaltung bietet. Es deckt alles ab, von Sitzungsverwaltung und Multi-Faktor-Authentifizierung bis hin zu Social Sign-Ons, Magic Links, E-Mail- oder SMS-Einmalpasswörtern und mehr.
Authentifizierungs- und Sicherheitsanforderungen, Trends und Best Practices entwickeln sich ständig weiter, da Datenschutz und Privatsphäre immer wichtiger werden. Indem Sie diese Verantwortung an einen spezialisierten Dienstleister verlagern, können Sie sich auf die Entwicklung der Kernfunktionen Ihrer Anwendung konzentrieren und schneller liefern.
Plattformen wie Clerk übernehmen diese Sicherheitsaufgaben für Sie.
Für dieses Projekt sind ein neues oder vorhandenes NestJS-Projekt, ein Clerk-Konto und eine Clerk-Anwendung sowie Bibliotheken wie Passport, Passport Strategy und das Clerk-Backend-SDK erforderlich.
Mit der Nest-CLI können Sie ganz einfach ein neues NestJS-Projekt einrichten. Führen Sie mit einem beliebigen Paketmanager Ihrer Wahl die folgenden Befehle aus, um eine neue Nest-Anwendung zu erstellen:
$ pnpm add -g @nestjs/cli $ nest new clerk-auth
Weitere Informationen finden Sie in der NestJS-Dokumentation.
Wenn Sie noch keins haben, erstellen Sie ein Clerk-Konto und richten Sie eine neue Anwendung im Clerk-Dashboard ein. Sie können auf der Clerk-Website loslegen.
Die erforderlichen Bibliotheken für dieses Projekt können mit diesem Befehl installiert werden:
$ pnpm add @clerk/backend @nestjs/config @nestjs/passport passport passport-custom
Erstellen Sie eine .env-Datei im Stammverzeichnis Ihres Projekts, um Variablen für verschiedene Umgebungen, Produktion, Entwicklung oder Staging zu verwalten.
Fügen Sie die folgenden Variablen hinzu und ersetzen Sie die Platzhalter durch die tatsächlichen Schlüssel, die Sie aus Ihrem Clerk-Konto-Dashboard erhalten haben.
# .env CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY CLERK_SECRET_KEY=YOUR_SECRET_KEY
Um mit dem ConfigService in der gesamten Anwendung auf Umgebungsvariablen zuzugreifen, importieren Sie das ConfigModule in das Root-AppModule.
// src/app.module.ts import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), ], }) export class AppModule {}
In diesem Abschnitt wird erläutert, wie Sie das Clerk-Backend-SDK in Ihr NestJS-Projekt integrieren und nutzen.
Durch die Registrierung des Clerk-Clients als Anbieter kann er mithilfe eines Dekorators in Klassen eingefügt werden, sodass er überall in der Codebasis verwendet werden kann, wo er benötigt wird, wie in den kommenden Abschnitten gezeigt wird.
$ pnpm add -g @nestjs/cli $ nest new clerk-auth
Als nächstes müssen Sie den Anbieter bei Nest registrieren, um die Abhängigkeitsinjektion zu aktivieren.
$ pnpm add @clerk/backend @nestjs/config @nestjs/passport passport passport-custom
Clerk stellt ein JWT-Token aus, wenn sich ein Benutzer über die von Clerk gehosteten Seiten oder eine Frontend-App anmeldet oder anmeldet. Dieses Token wird dann als Bearer-Token im Authorization-Header von Anfragen an die NestJS-Backend-Anwendung gesendet.
In NestJS ist Passport die empfohlene Methode zur Implementierung von Authentifizierungsstrategien. Sie erstellen eine benutzerdefinierte Clerk-Strategie, die Token mit dem Clerk-Client überprüft.
# .env CLERK_PUBLISHABLE_KEY=YOUR_PUBLISHABLE_KEY CLERK_SECRET_KEY=YOUR_SECRET_KEY
Die Methode „validate()“ gibt Benutzerdaten zurück, die NestJS automatisch an „request.user“ anhängt.
Erstellen Sie ein AuthModule, das die Clerk-Strategie bereitstellt und in das PassportModule integriert ist. Registrieren Sie dann das AuthModule im AppModule.
// src/app.module.ts import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), ], }) export class AppModule {}
// src/providers/clerk-client.provider.ts import { createClerkClient } from '@clerk/backend'; import { ConfigService } from '@nestjs/config'; export const ClerkClientProvider = { provide: 'ClerkClient', useFactory: (configService: ConfigService) => { return createClerkClient({ publishableKey: configService.get('CLERK_PUBLISHABLE_KEY'), secretKey: configService.get('CLERK_SECRET_KEY'), }); }, inject: [ConfigService], };
Geschützte Routen sind Routen, bei denen der Benutzer authentifiziert werden muss, bevor er darauf zugreifen kann.
Guards bestimmen anhand bestimmter Laufzeitbedingungen, ob eine bestimmte Anfrage von einem Routenhandler verarbeitet werden soll.
Wenn Sie alle Routen in Ihrer Anwendung standardmäßig schützen möchten, müssen Sie die folgenden Schritte ausführen:
// src/app.module.ts import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { ClerkClientProvider } from 'src/providers/clerk-client.provider'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), ], providers: [ClerkClientProvider], }) export class AppModule {}
// src/auth/clerk.strategy.ts import { User, verifyToken } from '@clerk/backend'; import { Injectable, Injectable, UnauthorizedException } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { PassportStrategy } from '@nestjs/passport'; import { Strategy } from 'passport-custom'; import { UsersService } from 'src/users/users.service'; import { Request } from 'express'; import { ClerkClient } from '@clerk/backend'; @Injectable() export class ClerkStrategy extends PassportStrategy(Strategy, 'clerk') { constructor( @Inject('ClerkClient') private readonly clerkClient: ClerkClient, private readonly configService: ConfigService, ) { super(); } async validate(req: Request): Promise<User> { const token = req.headers.authorization?.split(' ').pop(); if (!token) { throw new UnauthorizedException('No token provided'); } try { const tokenPayload = await verifyToken(token, { secretKey: this.configService.get('CLERK_SECRET_KEY'), }); const user = await this.clerkClient.users.getUser(tokenPayload.sub); return user; } catch (error) { console.error(error); throw new UnauthorizedException('Invalid token'); } } }
Da die meisten Ihrer Endpunkte standardmäßig geschützt sind, können Sie den Authentifizierungsschutz als globalen Schutz konfigurieren.
// src/auth/auth.module.ts import { Module } from '@nestjs/common'; import { ClerkStrategy } from './clerk.strategy'; import { PassportModule } from '@nestjs/passport'; import { ClerkClientProvider } from 'src/providers/clerk-client.provider'; import { ConfigModule } from '@nestjs/config'; @Module({ imports: [PassportModule, ConfigModule], providers: [ClerkStrategy, ClerkClientProvider], exports: [PassportModule], }) export class AuthModule {}
In diesen beiden Controllern wird der Public Decorator im AppController verwendet, um eine Route als öffentlich zu kennzeichnen. Im AuthController hingegen ist kein Dekorator erforderlich, um Routen als geschützt anzugeben, da der Authentifizierungsschutz standardmäßig global angewendet wird.
// src/app.module.ts import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { ClerkClientProvider } from 'src/providers/clerk-client.provider'; import { AuthModule } from 'src/auth/auth.module'; @Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, }), AuthModule, ], providers: [ClerkClientProvider], }) export class AppModule {}
// src/decorators/public.decorator.ts import { SetMetadata } from '@nestjs/common'; export const IS_PUBLIC_KEY = 'isPublic'; export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
Hinweis: Denken Sie daran, den AppController im AppModule und den AuthController im AuthModule zu registrieren.
Clerk übernimmt als Plattform die Authentifizierungs- und Sicherheitsaufgaben und hält sich dabei über die neuesten Trends und Best Practices auf dem Laufenden. Dadurch können Sie sich auf die Entwicklung der Kernfunktionen Ihrer Anwendung konzentrieren und Ihren Entwicklungsprozess beschleunigen.
In diesem Leitfaden haben wir die Schritte zur Implementierung der Clerk-Authentifizierung behandelt, von der Einrichtung des Projekts bis zur Sicherung von Routen. Diese grundlegenden Schritte sollen Ihnen den Einstieg in die Erkundung der Möglichkeiten einer Authentifizierungsdienstplattform erleichtern.
Ein voll funktionsfähiges Beispiel dieses Projekts finden Sie am Ende dieses Artikels.
Verwendung der Clerk-Authentifizierung und Benutzerverwaltung in der NestJS-Backend-Anwendung
Dieses Monorepo umfasst die folgenden Pakete und Apps:
Jedes Paket und jede App besteht zu 100 % aus TypeScript.
In diesem Monorepo sind einige zusätzliche Tools bereits für Sie eingerichtet:
Das obige ist der detaillierte Inhalt vonAuthentifizierung mit Clerk in der NestJS-Serveranwendung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!