ログインサービスを実施してみます.


ログインサービスを実施してみます.
JWTを使用してログインサービスを実施します.
(セッション/Cookieを使用して作成することも、JWTを使用して作成することも、トークンを使用して作成することもできます.)
JWTはJson webtokenと呼ばれ,json形式でユーザ情報を格納するWebタグといえる.
こうなる
Header:base 64符号化トークンのタイプとアルゴリズム
Payload:base 64符号化データ(キー値)
署名:ヘッダー/パスワードを組み合わせ、秘密鍵で署名し、base 64に符号化します.
naHeader.naPayload.na1Signature321
これは彼らのホームページです.
https://jwt.io/
認証プロセス
Front ------------------------- Back
1.要求の発行----------------鍵->JWTの生成
2.<---------------------------------------JWT発行
このリリースのJWTを保存しているところが多いのですが、
通常、ローカルストレージまたはHTTP Onlyクッキーに格納されます.
受け取ったJWTは認証のために書かれています.
記事を書いたり会員情報を変更したりするためにAPI Requestが送信され、このときヘッダにJWTが送信されます.
バックエンドはこのトークンを受信し、JWTGuardによってJWT Strategyが実行され、JWTStrategyはsecretKeyを使用して復号される.
この復号化後、ユーザ情報を読み出し、任意のAPIのビジネスロジックを実行し、応答値をフロントに渡す.
何の防御だ.
この英語はもっと読みやすい
Guards have a single responsibility. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as authorization.
next()関数を呼び出すと、どのプロセッサが実行されるか分からない愚かなミドルウェアとは異なり、ExecutionContextのインスタンスにアクセスし、次にどの操作が実行されるかを知ることができます.
その設計は異常フィルタ、パイプ、インタフェースによく似ており、要求/応答サイクルの正確な点で処理ロジックを挿入および宣言できます.
JWTを使用して作成
これはホールです
https://docs.nestjs.kr/security/authentication
JWTを使うのでJWT機能を使いました
公式サイトによると、これをインストールします.
$ npm install --save @nestjs/passport passport
$ npm install --save @nestjs/jwt passport-jwt
$ npm install --save-dev @types/passport-jwt
このコマンドを使用して、モジュールとサービスを作成します.
nest g module auth
nest g service auth
やるなら自分で見てアプリを作るモジュールをモジュールに挿入
作成したauthフォルダにjwtフォルダを作成し、保護カバーを作成します.
// src/auth/jwt/jwt.guard.ts
@Injectable()
//AuthGuard는 Strategy를 자동으로 실행시켜주는 기능을 가지고있다.
export class JwtAuthGuard extends AuthGuard('jwt') {}
今でも戦略を立ててください.
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'secretKey',
      ignoreExpiration: false,
    });
  }

  async validate(payload) {}
}

  • jwtFromRequestは、要求されたヘッダファイルからタグを抽出する

  • secretOrKeyは絶対に漏らしてはいけない鍵です環境変数として保存します.

  • Jwtには有効期限があります.永遠に存在すれば、ハッカーの危険がある.期限がfalseであることは無視できません

  • validate関数は検証セクションです.
  • 今は秋module.TSから依存関係を注入するように設定すればよい.
    @Module({
      imports: [
        //passportmodule은 가드에서 사용할 수 있도록 설정해준 것.
        //해주면 이제 가드 넘어가고, strategy 실행 됨.
        PassportModule.register({ defaultStrategy: 'jwt', session: false }),
        // JwtModule.register는 로그인할 때 쓰임.
        JwtModule.register({
          secret: 'secret',
          signOptions: { expiresIn: '1y' },
        }),
        // CatsModule의 exports에 넣은 것들을 사용할 수 있게됨.
        CatsModule,
      ],
      providers: [AuthService, JwtStrategy],
    })
    サービスビジネスロジックを作成します.
    // auth.service.ts
    import { Injectable, UnauthorizedException } from '@nestjs/common';
    import { CatsRepository } from 'src/cats/cats.repository';
    import { LoginRequestDto } from './dto/login.request.dto';
    import * as bcrypt from 'bcrypt';
    import { JwtService } from '@nestjs/jwt';
    
    @Injectable()
    export class AuthService {
      // cat의 db를 사용하기 위해 종속성 주입사용.
      constructor(
        private readonly catsRepository: CatsRepository,
        private jwtService: JwtService, //JwtModule이 제공해주는 공급자.
      ) {}
    
      async jwtLogIn(data: LoginRequestDto) {
        const { email, password } = data;
    
        // 해당하는 email이 있는지 체크
        const cat = await this.catsRepository.findCatByEmail(email);
    
        if (!cat) {
          throw new UnauthorizedException('이메일과 비밀번호를 확인해주세요');
        }
    
        // password가 일치하는지 체크
        const isPasswordValiadated: boolean = await bcrypt.compare(
          password,
          cat.password,
        );
    
        if (!isPasswordValiadated) {
          throw new UnauthorizedException('이메일과 비밀번호를 확인해주세요.');
        }
    
        //jwt 서비스를 사용해서 프론트엔드에게 전달.
        //jwt의 payload는 우리가 만들어줘야한다.
        // sub는 토큰의 제목을 의미.
        const payload = { email: email, sub: cat.id };
    
        // 토큰 만들어서 보내기. sign을 통해서 만들어준다.
        // asdfasdf.asdfasdf.asdfasd87fa 이렇게 만들어져서 보내짐.
        return {
          token: this.jwtService.sign(payload),
        };
      }
    }
  • catモジュールで現在作成されているauthサービスを使用するには、authモジュールがauthServiceをエクスポートします.
  • 猫モジュールはAuthModuleにインポートされます.
  • をモジュールのauthモジュールに導入したサービスを相関注入する.
  • 今は
  • を使っています.
  • export class CatsController {
      // CatsController라는 소비자가 catsService라는 제품을 주입받음.
      constructor(
        private readonly catsService: CatsService,
        private readonly authService: AuthService,
      ) {}
        @ApiOperation({ summary: '로그인' }) // Swagger 이름 설정.
      // 로그인
      @Post('login')
      logIn(@Body() data: LoginRequestDto) {
        return this.authService.jwtLogIn(data);
      }
    }