-
nest js auth카테고리 없음 2023. 12. 22. 12:48
auth.middleware.ts
import {
Injectable,
NestMiddleware,
UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthMiddleware implements NestMiddleware {
constructor(private jwtService: JwtService) {}
// eslint-disable-next-line @typescript-eslint/ban-types
async use(req: any, res: any, next: Function) {
const authHeader = req.headers.authorization;
if (!authHeader) {
throw new UnauthorizedException('JWT 토큰을 찾을 수 없습니다!');
}
let token: string;
try {
token = authHeader.split(' ')[1];
const payload = await this.jwtService.verify(token);
req.user = payload;
next();
} catch (err) {
throw new UnauthorizedException(`JWT 토큰이 올바르지 않습니다: ${token}`);
}
}
}
사용하려면 app.module에 넣어줘야한다.
import Joi from 'joi';
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthMiddleware } from './auth/auth.middleware';
import { Post } from './post/entities/post.entity';
import { PostModule } from './post/post.module';
import { User } from './user/entities/user.entity';
import { UserModule } from './user/user.module';
const typeOrmModuleOptions = {
useFactory: async (
configService: ConfigService,
): Promise<TypeOrmModuleOptions> => ({
type: 'mysql',
host: configService.get('DB_HOST'),
port: configService.get('DB_PORT'),
username: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'),
entities: [Post, User],
synchronize: configService.get('DB_SYNC'),
logging: true,
}),
inject: [ConfigService],
};
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
validationSchema: Joi.object({
DB_HOST: Joi.string().required(),
DB_PORT: Joi.number().required(),
DB_USERNAME: Joi.string().required(),
DB_PASSWORD: Joi.string().required(),
DB_NAME: Joi.string().required(),
DB_SYNC: Joi.boolean().required(),
}),
}),
TypeOrmModule.forRootAsync(typeOrmModuleOptions),
JwtModule.registerAsync({
useFactory: (config: ConfigService) => ({
secret: config.get<string>('JWT_SECRET_KEY'), // .env 파일에 JWT_SECRET_KEY라는 키로 비밀키를 저장해두고 사용합니다.
}),
inject: [ConfigService],
}),
PostModule,
UserModule,
],
controllers: [AppController],
providers: [AppService, AuthMiddleware],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(AuthMiddleware) // 미들웨어 적용!
.forRoutes({ path: 'user/check', method: RequestMethod.GET }); // user/check 엔드포인트에만 적용
}
}
login user dto
import { CreateUserDto } from './create-user.dto';
export class LoginUserDto extends CreateUserDto {
// 향후에, 추가로 필요한 로그인에 관련된 속성이 있다면 여기에 정의하시면 됩니다!
}
LOGIN USER CONTROLLER.TS
import { Body, Controller, Get, Post, Req } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { LoginUserDto } from './dto/login-user.dto';
import { UserService } from './user.service';
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Post('/login')
async login(@Body() loginUserDTO: LoginUserDto) {
return await this.userService.login(loginUserDTO);
}
@Post('/signup')
async createUser(@Body() createUserDTO: CreateUserDto) {
return await this.userService.create(createUserDTO);
}
@Get('/check')
checkUser(@Req() req: any) {
const userPayload = req.user;
return this.userService.checkUser(userPayload);
}
}
SERVICE
async login(LoginUserDto: LoginUserDto) {const { userId, password } = LoginUserDto;