😎 κ³΅λΆ€ν•˜λŠ” μ§•μ§•μ•ŒνŒŒμΉ΄λŠ” μ²˜μŒμ΄μ§€?

[Nest JS 둜 CRUD κ²Œμ‹œνŒ λ§Œλ“€κΈ°] (27) JWT λ₯Ό μ΄μš©ν•΄μ„œ 토큰 μƒμ„±ν•˜κΈ° λ³Έλ¬Έ

πŸ‘©‍πŸ’» λ°±μ—”λ“œ(Back-End)/Nest js

[Nest JS 둜 CRUD κ²Œμ‹œνŒ λ§Œλ“€κΈ°] (27) JWT λ₯Ό μ΄μš©ν•΄μ„œ 토큰 μƒμ„±ν•˜κΈ°

μ§•μ§•μ•ŒνŒŒμΉ΄ 2023. 6. 8. 17:52
728x90
λ°˜μ‘ν˜•

<λ³Έ λΈ”λ‘œκ·ΈλŠ” John Ahn μ˜ 유튜브λ₯Ό μ°Έκ³ ν•΄μ„œ κ³΅λΆ€ν•˜λ©° μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€ :-)>

=> λ”°λΌν•˜λ©΄μ„œ λ°°μš°λŠ” NestJS

 

🧸 JWT (JSON Web Token)

λ‘œκ·ΈμΈν•œ 고유 μœ μ €λ₯Ό μœ„ν•œ 토큰을 생성해야 함토큰을 생성할 λ•Œ JWT λͺ¨λ“ˆμ„ μ‚¬μš©ν•¨

 

λ‹Ήμ‚¬μžκ°„μ— 정보λ₯Ό json 개체둜 μ•ˆμ „ν•˜κ²Œ μ „μ†‘ν•˜κΈ° μœ„ν•œ μ»΄νŒ©νŠΈν•˜κ³  독립적인 방식을 μ •μ˜ν•˜λŠ” κ°œλ°©ν˜• ν‘œμ€€ (RFC 7519)

정보λ₯Ό μ•ˆμ „ν•˜κ²Œ μ „ν•  λ•Œ OR μœ μ €μ˜ κΆŒν•œ 같은 것을 체크할 λ•Œ μ‚¬μš©ν•¨

 

🧸 JWT ꡬ쑰 

πŸŽ€ Header

토큰에 λŒ€ν•œ 메타 데이터 포함 (νƒ€μž…, ν•΄μ‹± μ•Œκ³ λ¦¬μ¦˜, SHA256, RSA ..)

 

πŸŽ€ Payload

μœ μ € 정보, λ§Œλ£ŒκΈ°κ°„, 주제 λ“±

 

πŸŽ€ Verify Signature

토큰이 보낸 μ‚¬λžŒμ— μ˜ν•΄ μ„œλͺ…λ˜μ—ˆμœΌλ©° μ–΄λ–€ μ‹μœΌλ‘œλ“  λ³€κ²½λ˜μ§€ μ•Šμ•—λŠ”μ§€ ν™•μΈν•˜λŠ” μ„œλͺ…

헀더 및 νŽ˜μ΄λ‘œλ“œ μ„Έκ·Έλ¨ΌνŠΈ, μ„œλͺ… μ•Œκ³ λ¦¬μ¦˜, λΉ„λ°€ λ˜λŠ” κ³΅κ°œν‚€λ₯Ό μ‚¬μš©ν•˜μ—¬ 생성

 

🧸 JWT μ‚¬μš© 흐름

μœ μ € 둜그인 -> ν† ν° 생성 (Hashing μ•Œκ³ λ¦¬μ¦˜ + Secret Text) -> ν† ν° 보관

Admin 만 λ³Ό 수 μžˆλŠ” κΈ€ λ³Ό λ•Œ -> μš”μ²­μ„ 보낼 λ•Œ λ³΄κ΄€ν•˜κ³  μžˆλŠ” token μ„ header 에 λ„£μ–΄μ„œ 보냄
-> μ„œλ²„μ—μ„œλŠ” JWT μ΄μš©ν•΄μ„œ Token을 λ‹€μ‹œ μƒμ„±ν•œ ν›„ 두 개λ₯Ό 비ꡐ -> 톡과 되면 Admin κΈ€ λ³Ό 수 있음
비ꡐ : μ„œλ²„μ—μ„œ μš”μ²­μ—μ„œ 같이 온 header λž‘ payload κ°€μ Έμ˜€κ³ , μ„œλ²„ μ•ˆμ— 가지고 μž‡λŠ” secret μ΄μš©ν•΄μ„œ signature 뢀뢄을 λ‹€μ‹œ 생성 ! κ·Έ λ‘˜μ΄ μΌμΉ˜ν•˜λ©΄ 톡과

 

🧸 JWT ꡬ쑰 JWT λ₯Ό μ΄μš©ν•΄μ„œ ν† ν° μƒμ„±ν•˜κΈ° 

Passport : JWT μ΄μš©ν•΄μ„œ 인증 μ²˜λ¦¬ν•˜κ³  λ™μ˜ κ³Όμ • μ‰½κ²Œ λ§Œλ“€μ–΄ 쀌

 

πŸŽ€ ν•„μš”ν•œ λͺ¨λ“ˆλ“€

// nestjs μ—μ„œ jwt μ‚¬μš©ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ λͺ¨λ“ˆ
@nestjs/jwt

// nestjs μ—μ„œ passport λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ λͺ¨λ“ˆ
@nestjs/passport

// passport
passport

// jwt λͺ¨λ“ˆ
passport-jwt

npm install @nestjs/jwt @nestjs/passport passport passport-jwt --save

 

🧸 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— JWT λͺ¨λ“ˆ λ“±λ‘ν•˜κΈ°

πŸŽ€ auth λͺ¨λ“ˆ import μ•ˆμ— λ„£κΈ°

Secret : 토큰을 λ§Œλ“€ λ•Œ μ΄μš©ν•˜λŠ” Secret ν…μŠ€νŠΈ

ExpiresIn : μ •ν•΄μ§„ μ‹œκ°„ μ΄ν›„μ—λŠ” 토큰이 μœ νš¨ν•˜μ§€ μ•Šκ²Œ 됨 (60 * 60 은 ν•œμ‹œκ°„)

 

πŸŽ€ auth.module.ts

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';
import { AuthController } from './auth.controller';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: "jwt"}),
    JwtModule.register({
      // 토큰을 λ§Œλ“€ λ•Œ μ΄μš©ν•˜λŠ” Secret ν…μŠ€νŠΈ
      secret: "Secret1234", // μ•„λ¬΄κ±°λ‚˜ 해도 됨
      signOptions: {
        // 정해진 μ‹œκ°„ μ΄ν›„μ—λŠ” 토큰이 μœ νš¨ν•˜μ§€ μ•Šκ²Œ 됨 (60 * 60 은 ν•œμ‹œκ°„)
        expiresIn: 60 * 60,
      }
    }),
    TypeOrmModule.forFeature([UserRepository])
  ],
  controllers: [AuthController],
  providers: [AuthService]
})
export class AuthModule {}

 

🧸 둜그인 성곡 μ‹œ JWT μ΄μš©ν•΄μ„œ 토큰 μƒμ„±ν•˜κΈ°

1) Service μ—μ„œ SignIn λ©”μ†Œλ“œ μƒμ„±ν•˜κΈ°

auth λͺ¨λ“ˆμ— JWT λ₯Ό λ“±λ‘ν–ˆκΈ°μ—, Service μ—μ„œ JWT κ°€μ Έμ˜€κΈ°

 

2) Token λ§Œλ“œλ €λ©΄ secert, payload ν•„μš”ν•˜λ‹€

payload μ—λŠ” μžμ‹ μ΄ μ „λ‹¬ν•˜κ³ μž ν•˜λŠ” 정보λ₯Ό λ„£λŠ”λ‹€ (role, μœ μ €, 이메일 λ“±)

 

πŸŽ€ auth.module.ts

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';
import { AuthController } from './auth.controller';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: "jwt"}),
    JwtModule.register({
      // 토큰을 λ§Œλ“€ λ•Œ μ΄μš©ν•˜λŠ” Secret ν…μŠ€νŠΈ
      secret: "Secret1234", // μ•„λ¬΄κ±°λ‚˜ 해도 됨
      signOptions: {
        // 정해진 μ‹œκ°„ μ΄ν›„μ—λŠ” 토큰이 μœ νš¨ν•˜μ§€ μ•Šκ²Œ 됨 (60 * 60 은 ν•œμ‹œκ°„)
        expiresIn: 60 * 60,
      }
    }),
    TypeOrmModule.forFeature([UserRepository])
  ],
  controllers: [AuthController],
  providers: [AuthService]
})
export class AuthModule {}
728x90
λ°˜μ‘ν˜•
Comments