π 곡λΆνλ μ§μ§μνμΉ΄λ μ²μμ΄μ§?
[Nest JS λ‘ CRUD κ²μν λ§λ€κΈ°] (27) JWT λ₯Ό μ΄μ©ν΄μ ν ν° μμ±νκΈ° λ³Έλ¬Έ
[Nest JS λ‘ CRUD κ²μν λ§λ€κΈ°] (27) JWT λ₯Ό μ΄μ©ν΄μ ν ν° μμ±νκΈ°
μ§μ§μνμΉ΄ 2023. 6. 8. 17:52<λ³Έ λΈλ‘κ·Έλ 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 {}