Nest.js上でGraphQL APIのユーザー認証JWT Tokenを作成する


🧑🏻‍💻 参照コードのスペース:https://docs.nestjs.com/security/authentication
バックエンドサーバでログイン認証機能を実現するためにnestjsの正式なドキュメントを参照し、jwt機能を使用しました.
今度のPostingは私が再びnestに来ますこれは、jsのjwtを貼り付けようとしたときに、アクセスして表示するための整理です.
この文章を読んで得られる知識
  • graphql resovlerによって要求および処理が必要なAPIにログインユーザの情報がある場合にのみ、これらのAPIを処理する必要がある場合にユーザを確認することができ、ユーザが正しい場合には、APIを正常に動作させる役割を実行することができる.
  • nest.graphqlを介してjsを介してAPIを処理すると仮定する.
    app.modules.ts
    @Module({
      imports: [
        GraphQLModule.forRoot({ //graphql을 연결하기 위한 초기 설정 입니다.
          debug: true,
          playground: true,
          installSubscriptionHandlers: true,
          autoSchemaFile: 'schema.gql',
          context: ({ req, connection }) => { //graphql에게 request를 요청할때 req안으로 jwt토큰이 담깁니다.
            if (req) {
              //이부분이 처음 보시는 분들에게는 의아할 수 있습니다. graphql을 사용하면서 req.headers.authorization를 어떻게 담아서 보내는거지? 하실 수 있습니다. 해당 부분은 밑에 부분에서 설명하겠습니다.
              const user = req.headers.authorization;
              return { ...req, user };
            } else {
              return connection;
            }
          },
        }),
        AuthModule,
      ],
      providers: [GqlAuthGuard],
    })
    
    上に見えるREQheaders.ライセンスセクションについて説明する必要があります.私たちはrequestヘッダで通信します.したがって,ユーザが認証を望む場合には,ユーザの情報が必要となる.ヘッダーに置いて「私はこのユーザーで、私のコインはこれです」と要求します.
    では本題に戻ってGraphsql運動場でどうやってreqしますか?ヘッダーにユーザー情報トークンを追加できますか?

    Graphsql遊園地は、上図のようにHTTP Headersを提供しています.
    したがって、jwtで受信したtoken情報をこのセクションに送信できます.
    表の場合、
    {"Authorization":"Bearer 토큰정보"}
    フォーマットで送信します.
    {「認証」:「トークン情報」}👈 私と一緒にシャベルを何度も作りました.ご注意ください.
    これでappmodules.tsで作成すべき初期設定が完了しました.
    これで、初期設定コードの2つのコードを表示する必要があります.
    アイデンティティーモジュール、GqlAutheGuardセクション.順番に見ます
    auth.module.ts
    import { Module } from '@nestjs/common';
    import { JwtModule } from '@nestjs/jwt';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { UserRepository } from 'src/user/user.repository';
    import { AuthResolver } from './auth.resolver';
    import { AuthService } from './auth.service';
    import { JwtStrategy } from './jwt.strategy';
    import { jwtConstants } from './jwtContans';
    
    @Module({
      imports: [
        //이번 기회를 통해서 얻은 부분중 하나입니다. jwt를 사용하려면 사용하려는 곳에 jwtModule을 import해줘야합니다.
        JwtModule.register({
          secret: jwtConstants.secret, //해당 부분은 jwtContants파일에 secret이라는 secret를 만들어서 넣어주었습니다 필수로 필요합니다! jwt는 크게 3가지 형식으로 이루어져있습니다. header,payload,signiture verify로 이루어져있는데 우리가 가지고자 하는 유저정보의 경우에는 payload에 들어가게되는데 해당 json정보를 암호화할 방식을 결정하는 장치가 됩니다.!
          signOptions: { expiresIn: '1 day' },// 해당부분은 토큰의 유지기간을 설정하는 부분입니다.
        }),
      ],
      providers: [AuthService, AuthResolver, JwtStrategy],//이부분들 역시도 인증과 관련된 부분을 구현하기위해서 필요한 파일입니다.
      exports: [],
    })
    export class AuthModule {}
    上のファイルに示すように、今から始めることができます.
    サプライヤーに関する部分を見てみましょう.
    JwtStrategy.tsから始めましょう.
    해당 파일의 역할은 jwt를 통하여 req, res를 하고자할때 initialization하는 역할과 같다라는 느낌을 받았습니다.
    import { ExtractJwt, Strategy } from 'passport-jwt';
    import { PassportStrategy } from '@nestjs/passport';
    import { Injectable } from '@nestjs/common';
    import { jwtConstants } from './jwtContans';
    
    @Injectable()
    export class JwtStrategy extends PassportStrategy(Strategy) {
      constructor() {
        super({
          jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
          ignoreExpiration: false,
          secretOrKey: jwtConstants.secret,
        });
      }
    
      async validate(payload: any) {
        return { userId: payload.sub, username: payload.username };
      }
    }
    JwtStrategy.tsのファイル構造は以下の通りである.PassportStrategを継承するJWTStrategyclass,authを作成します.module.tsのクラスがオブジェクトとして作成され、メモリに格納されると、jwtに関連する受信情報のコードを初期化することを理解します.
    次に、
    AuthService.ts
    import { Injectable, Logger } from '@nestjs/common';
    import { JwtService } from '@nestjs/jwt';
    import { InjectRepository } from '@nestjs/typeorm';
    import { env } from 'process';
    import { UserRepository } from 'src/user/user.repository';
    import { jwtConstants } from './jwtContans';
    
    @Injectable()
    export class AuthService {
      private logger: Logger;
      constructor(
        @InjectRepository(UserRepository)
        private userRepository: UserRepository,
        private jwtService: JwtService,
      ) {
        this.logger = new Logger('AuthService');
      }
    
      async login(email: string, password: string): Promise<String> {
        const user = await this.userRepository.userFindOne(email, password);
    
        if (user) {
          const { ...result } = user;
          this.logger.log('validateUser Result: ', result);
    
          const payload = { username: user.email, sub: user.id };
    
          return this.jwtService.sign(payload);
        }
      }
    }
    
    AuthResolver.TSファイルに作成するAPIの作成方法のサービスファイル.
    AuthResolver.ts
    import { Logger, UseGuards } from '@nestjs/common';
    import {
      Resolver,
      Query,
      Mutation,
      Args,
      Context,
      GqlContextType,
    } from '@nestjs/graphql';
    import { UserEntity } from 'src/entities/user.entity';
    import { GqlAuthGuard } from 'src/gql-auth-guard/gql-auth-guard.service';
    import { UserObject } from 'src/user/dto/user.object';
    import { AuthService } from './auth.service';
    import { AuthDTO } from './dto/auth.dto';
    
    export interface Context {
      user?: any;
    }
    @Resolver()
    export class AuthResolver {
      private logger: Logger;
      constructor(private authService: AuthService) {
        this.logger = new Logger('AuthResolver');
      }
    
      @Query(() => String)
      async login(@Args('data') data: AuthDTO) {
        try {
          const { email, password } = data;
          const token = this.authService.login(email, password);
    
          return token;
        } catch (e) {
          this.logger.error(e);
          return false;
        }
      }
    }
    対応する解析器でログインします.ログインに成功すると、
    jwtでtokenを作成します.今ここにいる.
    生成したtokenをgraphsql遊園地のHTTPヘッダに入れます.
    仕事をさせる.
    このようなjwt tokenはどのように使いますか?
    私が作成するプロジェクトでは、postは1人のユーザーのみがログインできるプロジェクトであり、上記の説明で作成したjwtタグを使用することができます.
    ユーザーである場合は、apiのコードを起動するには、ユーザーであるかどうかを確認します.
    import { UseGuards } from '@nestjs/common';
    import { Resolver, Query, Args, Mutation } from '@nestjs/graphql';
    import { GqlAuthGuard } from 'src/gql-auth-guard/gql-auth-guard.service';
    import { CreatePostInputDTO } from './dto/create-post-input.dto';
    import { PostObject } from './dto/post.object';
    import { PostService } from './post.service';
    
    @Resolver()
    export class PostResolver {
      constructor(private readonly postService: PostService) {}
      @UseGuards(GqlAuthGuard) //이부분이 가장 핵심이 되는 기능입니다. nestjs의 강력한 기능중 하나라고 생각합니다. 메소드를 따로 만들어서 유저가 보낸 jwt정보를 확인하지 않고 위에서 GqlAuthGuard만들어놓은 해당 파일을 불러서 써줌으로써 확인을 해줍니다. 너무 좋네요 :)
      @Mutation(() => Boolean)
      async createPost(@Args('data') data: CreatePostInputDTO): Promise<boolean> {
        const { title } = data;
        return await this.postService.createPost({ title });
      }
    }
    
    GqlAuthGuardファイルはどんなものですか!そう聞いてもいいです.これらのファイルには、次のものが含まれます.
    import { ExecutionContext, Injectable } from '@nestjs/common';
    import { GqlExecutionContext } from '@nestjs/graphql';
    import { AuthGuard } from '@nestjs/passport';
    
    @Injectable()
    export class GqlAuthGuard extends AuthGuard('jwt') {
      getRequest(context: ExecutionContext) {
        const ctx = GqlExecutionContext.create(context);
    
        return ctx.getContext().req;
      }
    }
    Nestに似てるjsが提供するAuthGuardを継承
    getRequestをgraphQLに適合させるには、getRequestを変更して使用します:)
    以上は私が見たいNestですjs以上はGraphQL APIのユーザ認証JWT Tokenを作成する.
    何か足りない説明や不正確な情報があれば、いつでもフィードバックしてください.ありがとうございます.🧑🏻‍💻 みんな楽しんで!