ホームページ >ウェブフロントエンド >jsチュートリアル >Passport を使用して NestJS に JWT 認証を実装する日 (パート 1)
ネスト g リソース認証
さらに選択を求められます
❯ REST API
GraphQL (コードファースト)
GraphQL (スキーマファースト)
マイクロサービス (非 HTTP)
WebSocket
REST API を選択すると、dtos サービス コントローラーとモジュールを使用してモジュール全体が生成されます
最初のステップとして電子メール/パスワードベースの認証を実装しているため、ユーザーを登録します。
nest js はクラスバリデーターのような推奨される検証パッケージと強力に統合されているため、以前の経験から、react js フロントエンドの検証ロットに zod を使用しているため、素晴らしいものを見つけました
ネスト zod と呼ばれるネスト JS エコシステムのソリューションなので、今のところはこれを使用することを好みます。始めるには、まずライブラリをインストールします
npm 私はnestjs-zod
import { createZodDto } from 'nestjs-zod'; import { z } from 'zod'; const passwordStrengthRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; const registerUserSchema = z .object({ email: z.string().email(), password: z .string() .min(8) .regex( passwordStrengthRegex, 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character', ), confirmPassword: z.string().min(8), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', }); export class RegisterUserDto extends createZodDto(registerUserSchema) {}
その後、ルートに検証パイプを適用します
import { Controller, Post, Body, Version, UsePipes } from '@nestjs/common'; import { AuthService } from './auth.service'; import { RegisterUserDto } from './dto/register.dto'; import { ZodValidationPipe } from 'nestjs-zod'; @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @Version('1') @Post() @UsePipes(ZodValidationPipe) async registerUser(@Body() registerUserDto: RegisterUserDto) { return await this.authService.registerUser(registerUserDto); } }
すべての入力が正しい場合
これで最初のステップは完了です
3 つの入力があります
ただし、電子メール z.string().email() を明示的に追加しました。これはこのユースケースには十分です
しかし、セキュリティをさらに強化するために、サニタイズ層を追加できます
import { createZodDto } from 'nestjs-zod'; import { z } from 'zod'; import * as xss from 'xss'; const passwordStrengthRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; const registerUserSchema = z .object({ email: z.string().transform((input) => xss.filterXSS(input)), // Sanitizing input using xss password: z .string() .min(8) .regex( passwordStrengthRegex, 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character', ), confirmPassword: z.string().min(8), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', }); export class RegisterUserDto extends createZodDto(registerUserSchema) {}
これは、私たちが再度追加したテストでもありました
メール: z
.string()
.email()
import { createZodDto } from 'nestjs-zod'; import { z } from 'zod'; const passwordStrengthRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; const registerUserSchema = z .object({ email: z.string().email(), password: z .string() .min(8) .regex( passwordStrengthRegex, 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character', ), confirmPassword: z.string().min(8), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', }); export class RegisterUserDto extends createZodDto(registerUserSchema) {}
注目すべき主な点は、データ関連のない成功メッセージを返しただけです
このステップではユーザーにデータを返送する必要がないため、ID や電子メールなどのユーザーに送信します。登録後、ユーザーは詳細を入力するためにログイン ページにリダイレクトされるため、不必要なデータの送信を避けることはセキュリティ上の良い習慣です
nestjs でのレート制限の実装は非常に簡単で、nestjs/throttler をインストールしてグローバルに設定するだけで完了です。
パッケージをインストールするには npm i --save @nestjs/throttler
を実行します
import { Controller, Post, Body, Version, UsePipes } from '@nestjs/common'; import { AuthService } from './auth.service'; import { RegisterUserDto } from './dto/register.dto'; import { ZodValidationPipe } from 'nestjs-zod'; @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @Version('1') @Post() @UsePipes(ZodValidationPipe) async registerUser(@Body() registerUserDto: RegisterUserDto) { return await this.authService.registerUser(registerUserDto); } }
次に、nestjs スロットル ガードをグローバル ガードとして追加します
import { createZodDto } from 'nestjs-zod'; import { z } from 'zod'; import * as xss from 'xss'; const passwordStrengthRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; const registerUserSchema = z .object({ email: z.string().transform((input) => xss.filterXSS(input)), // Sanitizing input using xss password: z .string() .min(8) .regex( passwordStrengthRegex, 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character', ), confirmPassword: z.string().min(8), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', }); export class RegisterUserDto extends createZodDto(registerUserSchema) {}
これがこれです
import { BadRequestException, Injectable, InternalServerErrorException, } from '@nestjs/common'; import { RegisterUserDto } from './dto/register.dto'; import { PrismaService } from 'src/prismaModule/prisma.service'; import * as argon2 from 'argon2'; @Injectable() export class AuthService { constructor(private readonly prismaService: PrismaService) {} async registerUser(registerUserDto: RegisterUserDto) { // data is validate and sanitized by the registerUserDto const { email, password } = registerUserDto; try { // check if user already exists const user = await this.prismaService.user.findFirst({ where: { email, }, }); if (user) { throw new BadRequestException('user already eists '); } //if use not exists lets hash user password const hashedPassword = await argon2.hash(registerUserDto.password); // time to create user const userData = await this.prismaService.user.create({ data: { email, password: hashedPassword, }, }); if (!userData) { throw new InternalServerErrorException( 'some thing went wrong while registring user', ); } // if user is created successfully then send email to user for email varification return { success: true, message: 'user created successfully', }; } catch (error) { throw error; } } }
ユーザー エンドポイントの登録は機密性の高いエンドポイントのブルート フォースであるため、
または辞書攻撃が発生する可能性があるため、レート制限は厳密に保たれています
ユーザーに確認メールを送信するための再送信は、使いやすい素晴らしいサービスです。しかし、誰もが理解しやすいように、通知サービス全体について別のエピソードを作成することにしました
以上がPassport を使用して NestJS に JWT 認証を実装する日 (パート 1)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。