오늘로 JWT를 끝낸다는 생각으로 구현을 해봤습니다!!
src/app.module.ts
import { ChatGptAiModule } from './chat-gpt-ai/chat-gpt-ai.module';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { AuthModule } from './auth/auth.module';
import * as mongoose from 'mongoose';
@Module({
@@ -18,7 +19,8 @@ import * as mongoose from 'mongoose';
UserModule,
S3Module,
VideoModule,
ChatGptAiModule,
AuthModule],
controllers: [AppController],
providers: [AppService],
})
src/auth/auth.module.ts
import { Module, forwardRef } from '@nestjs/common';
import { AuthService } from './auth.service';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { JwtStrategy } from './jwt/jwt.strategy';
import { UserRepository } from 'src/user/user.repository';
import { UserModule } from 'src/user/user.module';
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt', session: false }),
JwtModule.register({
secret: 'secret',
signOptions: { expiresIn: '1y' },
}),
forwardRef(() => UserModule),
],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
})
export class AuthModule {}
src/auth/auth.service.ts
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UserRepository } from 'src/user/user.repository';
import { LoginRequestDto } from './dto/login.request.dto';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
constructor(
private readonly userRepository: UserRepository,
private jwtService: JwtService,
) {}
async jwtLogIn(data: LoginRequestDto) {
const { id, password } = data;
//* 해당하는 email이 있는지
const user = await this.userRepository.findUserById(id);
if (!user) {
throw new UnauthorizedException('아이디와 비밀번호를 확인해주세요.');
}
//* password가 일치한지
const isPasswordValidated: boolean = await bcrypt.compare(
password,
user.password,
);
if (!isPasswordValidated) {
throw new UnauthorizedException('아이디와 비밀번호를 확인해주세요.');
}
const payload = { id: id, sub: user.id };
return {
token: this.jwtService.sign(payload),
};
}
}
src/auth/dto/login.request.dto.ts
import { PickType } from '@nestjs/swagger';
import { User } from 'src/user/user.schema';
export class LoginRequestDto extends PickType(User, [
'id',
'password',
] as const) {}
src/auth/jwt/jwt.guard.ts
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
src/auth/jwt/jwt.strategy.ts
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: 'secret',
ignoreExpiration: false,
});
}
//async validate(payload) {}
}
src/user/user.controller.ts
import { UserRequestDto } from './dto/user.request.dto';
import { ApiOperation, ApiResponse } from '@nestjs/swagger';
import { ReadOnlyUserDto } from './dto/user.dto';
import { AuthService } from 'src/auth/auth.service';
import { LoginRequestDto } from 'src/auth/dto/login.request.dto';
@Controller('user')
@UseInterceptors(SuccessInterceptor)
@UseFilters(HttpExceptionFilter)
export class UserController {
constructor(
private readonly userService: UserService,
private readonly authService: AuthService,
) {}
@ApiOperation({ summary: '현재 유저 가져오기' })
@Get()
@@ -36,8 +41,8 @@ export class UserController {
@ApiOperation({ summary: '로그인' })
@Post('login')
logIn(@Body() data: LoginRequestDto) {
return this.authService.jwtLogIn(data);
}
@ApiOperation({ summary: '로그아웃' })
src/user/user.module.ts
import { Module, forwardRef } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './user.schema';
import { UserRepository } from './user.repository';
import { AuthModule } from 'src/auth/auth.module';
@Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
forwardRef(() => AuthModule),
],
controllers: [UserController],
providers: [UserService, UserRepository],
exports: [UserService, UserRepository],
})
export class UserModule {}
src/user/user.repository.ts
@InjectModel(User.name) private readonly userModel: Model<User>,
) {}
async findUserById(id: string): Promise<User | null> {
const users = await this.userModel.findOne({ id });
return users;
}
async existsById(id: string): Promise<boolean> {
const result = await this.userModel.exists({ id });
if (result) return true;
이렇게 구현을 해서
토큰 생성까지 성공했습니다!!!
이제 인증 부분만 구현하면 끝입니다!
이걸 하루 만에 해내는 다른 분들이 대단하다고 생각하고 더 열심히 공부해야 될 거 같습니다 :)
정말 유익한 글이었습니다.