ローカル戦略を用いたNESTJSパスポート認証の実現方法


このポストでは、パスポートローカル戦略を使用してNESTJSパスポート認証を実装する方法を学びます.認証は、任意の生産レベルのアプリケーションの重要な側面です.認証を扱う多くの方法がありますが、より人気のある方法の一つはパスポートを使うことです.
あなたがNESTJSのNESTJSに新しいならばNestJS Basics . しかしながら、あなたがNESTJSで認証を始める方法を学ぶことに主に興味があるならば、あなたはこのポストを続けることができます.

1 -パスポートは何ですか?
パスポートは人気のあるnodejsライブラリです.これは認証目的に使用され、いくつかの戦略と一緒に来る.これらの戦略は基本的に異なる認証メカニズムを実装する.我々の例では、ローカル戦略を使用します.この戦略はユーザ名とパスワードを使います.

パスポートは以下の手順を実行します.
  • ユーザの資格情報を認証する.これらの資格情報は、ユーザー名/パスワード、JWTトークンまたは任意の他のアイデンティティトークンです.
  • JWTトークンを発行することで認証状態を管理します.
  • リクエストオブジェクトにユーザーについての情報を添付します.
  • 物事を楽にする@nestjs/passport モジュール全体のパスポート使用パターンを身近なNESTJS構造にラップします.これは非常に簡単にnestjsパスポート認証を実装することができます.

  • 2 -インストールパッケージ
    ローカル戦略を有効にするには、必要なパッケージを以下のようにインストールする必要があります.
    $ npm install --save @nestjs/passport passport passport-local
    $ npm install --save-dev @types/passport-local
    
    パスポートは、ユーザー名/パスワード認証を実装するパスポートローカル戦略を提供します.また、インストールする@nestjs/passport パスポートパッケージ.最後に@types/passport-local パッケージは、開発中に型スクリプトの種類を助けます.
    注-任意の戦略のために、我々は常に@ nestjs/パスポートとパスポートパッケージをインストールする必要があります.番目のパッケージは、実装しようとしている戦略に依存します.ローカル戦略については、パスポートローカルをインストールします.同様に、JWT戦略のためにpassport-jwt 戦略パッケージにも戦略に依存します.
    インストールを行うと、今すぐアプリケーションを構築を開始しましょう.

    3 -モジュールの作成
    最初のステップとして、アプリケーションを適切なモジュールに分割しましょう.Authモジュールとユーザーモジュールを作成します.基本的に、Authモジュールはユーザを認証するためのロジックを含みます.一方、ユーザモジュールにはユーザ情報が含まれます.
    このビューを使用すると、以下のモジュールとその関連サービスを作成します.
    $ nest g module auth
    $ nest g service auth
    $ nest g module users
    $ nest g service users
    
    
    次はパスポート戦略を構築することです.戦略の構成には、次の2つの典型的な手順があります.
  • 最初に特定の戦略に固有のオプションのセットです.例えば、JWT戦略はトークンに署名する秘密を必要とします.
  • 2番目は検証コールバックです.言い換えると、我々はパスポートにどのようにユーザーが有効かどうかを確認する方法を伝えます.パスポートは、このコールバックが検証が成功した場合、完全なユーザオブジェクトを返すことを期待します.また、検証が失敗した場合はNULLを返す必要があります.失敗はユーザが存在しないことを意味する.パスポートローカルのような戦略のために、それはパスワードが無効であることを意味することもできます.
  • NESTJSパスポートパッケージはヘルパークラスを提供することによって上記の2つのステップに役立ちます.

    4 -ユーザサービスの実施
    まず最初にユーザサービスを作成しましょう.下記の例を参照ください.
    import { Injectable } from '@nestjs/common';
    
    export type User = any;
    
    @Injectable()
    export class UsersService {
    
        private readonly users = [
            {
                userId: 1,
                username: 'John Marston',
                password: 'rdr1',
            },
            {
                userId: 2,
                username: 'Arthur Morgan',
                password: 'rdr2',
            },
        ]
    
        async findOne(username: string): Promise<User | undefined> {
            return this.users.find(user => user.username === username)
        }
    }
    
    我々のデモ例については、我々のユーザーサービスは、単にハードコード化された有効なユーザーのリストを含みます.しかし、実際のアプリケーションでは、おそらくユーザデータベースを作成し、適切なテーブルからユーザーを取得しますNestJS TypeORM or NestJS Sequelize libraries . また、MongoDBを使用してNestJS Mongoose 図書館.
    上の例ではfindOne() メソッドはユーザーをユーザー配列から取得します.また、以下のようにユーザモジュールのためのエクスポート配列を更新する必要があります.
    import { Module } from '@nestjs/common';
    import { UsersService } from './users.service';
    
    @Module({
      providers: [UsersService],
      exports: [UsersService]
    })
    export class UsersModule {}
    

    5 - Authサービスの実装
    次のステップとしてAuthサービスをAuthモジュールに実装します.
    下記を参照
    import { Injectable } from '@nestjs/common';
    import { UsersService } from 'src/users/users.service';
    
    @Injectable()
    export class AuthService {
        constructor(private usersService: UsersService){}
    
        async validateUser(username: string, password: string): Promise<any> {
            const user = await this.usersService.findOne(username);
    
            if (user && user.password === password) {
                const {password, ...result} = user
                return result
            }
            return null
        }
    }
    
    基本的に、Authサービスは、ユーザを検索して、パスワードを確認する仕事をします.ご覧の通り、我々はvalidateUser() メソッド.ユーザーサービスを使用してユーザーを取得し、ユーザーオブジェクトを出力として返します.ただし、返される前に、パスワードプロパティをオブジェクトから取り除きます.
    最後に、ユーザモジュールをインポートするためにAuthModuleを更新します.この手順がなければ、Authモジュールでユーザサービスを使用できません.
    import { Module } from '@nestjs/common';
    import { UsersModule } from 'src/users/users.module';
    import { AuthService } from './auth.service';
    
    @Module({
      imports: [UsersModule],
      providers: [AuthService]
    })
    export class AuthModule {}
    

    6 -パスポートローカル戦略を実装する
    これはNESTJSパスポート認証を実装する際の重要なステップです.
    基本的に、パスポートのローカル戦略を実装する必要があります.これを行うには、ローカルという名前のファイルを作成します.戦略Authフォルダのts.
    import { Injectable, UnauthorizedException } from "@nestjs/common";
    import { PassportStrategy } from "@nestjs/passport";
    import { Strategy } from "passport-local";
    import { AuthService } from "./auth.service";
    
    @Injectable()
    export class LocalStrategy extends PassportStrategy(Strategy) {
        constructor(private authService: AuthService) {
            super()
        }
    
        async validate(username: string, password: string): Promise<any> {
            const user = await this.authService.validateUser(username, password);
    
            if (!user) {
                throw new UnauthorizedException();
            }
    
            return user;
        }
    }
    
    基本的には、PassportStrategyクラスを拡張するクラスローカル戦略を作成します.また、クラス定義で属性戦略を渡します.戦略はパスポートパッケージではなくパスポートローカルから輸入されることに注意してください.
    コンストラクタでは、単にsuper() メソッド.ローカル戦略はユーザー名とパスワードフィールドだけを予想します、したがって、構成オプションは必要でありません.しかし、必要に応じてSUM ()を呼び出しながら余分なプロパティを渡すことができます.
    次に、validate() PassportStrategyクラスの一部としてのメソッドです.すべての戦略については、パスポートは、検証機能を呼び出します.nestjsでは、この関数はvalidate() メソッド.戦略に基づいて、いくつかの議論を期待している.たとえば、ローカル戦略では、ユーザー名とパスワードの属性を期待します.
    論理的観点から、この方法は非常に簡単です.それは単にvalidateUser() Authサービスからのメソッド.有効なユーザが見つかれば、それは同じことを返します.それ以外の場合は例外をスローします.重い仕事の大部分はAuth Serviceで行われます.
    最後に、以下のようにAuthモジュールを更新してパスポートモジュールを使用する必要があります.
    import { Module } from '@nestjs/common';
    import { PassportModule } from '@nestjs/passport';
    import { UsersModule } from 'src/users/users.module';
    import { AuthService } from './auth.service';
    import { LocalStrategy } from './local.strategy';
    
    @Module({
      imports: [UsersModule, PassportModule],
      providers: [AuthService, LocalStrategy]
    })
    export class AuthModule {}
    

    7 -ログインルートを作成する
    今、ログインルートを作成できます.基本的に、このルートはユーザを認証するために使用されます.
    import { Controller, Post, Request, UseGuards } from '@nestjs/common';
    import { AuthGuard } from '@nestjs/passport';
    
    @Controller()
    export class AppController {
    
      @UseGuards(AuthGuard('local'))
      @Post('login')
      async login(@Request() req) {
        return req.user;
      }
    }
    
    ご覧の通り、我々は標準を使用します@Controller() デコレータ.また、我々@Post() のためにlogin() リクエストハンドラ.あなたがコントローラを作成することについてもっと知りたいならばNestJS Controllers .
    ここで注意すべき重要な点は@ useguard ( authguard (' local '))のデコレータです.基本的に、authguardは@ nestjs/passportパッケージによって提供される特別なガードです.このガードはパスポートのローカル戦略を拡張したときにプロビジョニングされた.
    この内蔵ガードはパスポートの戦略を呼び出し、プロセス全体を開始します.言い換えると、AuthGuard(この場合、ローカル)の戦略に基づいて、このガードは資格情報を取得し、検証関数を実行し、ユーザープロパティを作成します.
    ユーザーは、単に/login 以下の経路
    $ curl -X POST http://localhost:3000/auth/login -d '{"username": "John Marston", "password": "rdr1"}' -H "Content-Type: application/json"
    
    ユーザーが有効な場合、応答してユーザーオブジェクトを受け取ります.その他、HTTPステータス401または不正アクセスを受信します.

    結論
    これにより,パスポート局所戦略を用いてnestjsパスポート認証をいかに実装するかを学習した.
    我々は、必要なパッケージをインストールし、ユーザーを取得し、それらを認証するモジュールを構築することから始めた.最後に,パスポート認証プロセスをトリガーするログイン経路を実装した.
    この投稿用のコードはGithub .
    次のポストでは、我々はNestJS Passport JWT Strategy .
    あなたがどんなコメントか質問をするならば、下記のコメント部で彼らに言及するのが自由に感じてください.