Skip to content

Commit

Permalink
Merge pull request #43 from boostcampwm-2024/feature/api/login-#7
Browse files Browse the repository at this point in the history
[BE] 2.04 oAuth를 활용한 로그인 API 구현 #7
  • Loading branch information
jinddings authored Nov 11, 2024
2 parents bbcb40e + e1dda3f commit 3e0df74
Show file tree
Hide file tree
Showing 15 changed files with 403 additions and 44 deletions.
81 changes: 81 additions & 0 deletions BE/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion BE/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,23 @@
"@nestjs/schedule": "^4.1.1",
"@nestjs/swagger": "^8.0.1",
"@nestjs/typeorm": "^10.0.2",
"@types/passport-jwt": "^4.0.1",
"@nestjs/websockets": "^10.4.7",
"@types/cookie-parser": "^1.4.7",
"@types/passport-jwt": "^4.0.1",
"axios": "^1.7.7",
"bcrypt": "^5.1.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"cookie-parser": "^1.4.7",
"cross-env": "^7.0.3",
"docker": "^1.0.0",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"fastify-swagger": "^5.1.1",
"mysql2": "^3.11.3",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"passport-kakao": "^1.0.1",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"socket.io": "^4.8.1",
Expand Down
13 changes: 2 additions & 11 deletions BE/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,17 @@ import { ScheduleModule } from '@nestjs/schedule';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';
import { User } from './auth/user.entity';
import { StockIndexModule } from './stock/index/stock-index.module';
import { StockTopfiveModule } from './stock/topfive/stock-topfive.module';
import { KoreaInvestmentModule } from './koreaInvestment/korea-investment.module';
import { SocketModule } from './websocket/socket.module';
import { typeOrmConfig } from './configs/typeorm.config';

@Module({
imports: [
ScheduleModule.forRoot(),
ConfigModule.forRoot(),
TypeOrmModule.forRoot({
type: 'mysql', // 데이터베이스 타입
host: process.env.DB_HOST,
port: 3306,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWD,
database: process.env.DB_DATABASE,
entities: [User],
synchronize: true,
}),
TypeOrmModule.forRoot(typeOrmConfig),
KoreaInvestmentModule,
AuthModule,
StockIndexModule,
Expand Down
57 changes: 52 additions & 5 deletions BE/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@ import {
Post,
Get,
Body,
Req,
ValidationPipe,
UseGuards,
Req,
Res,
UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiOperation } from '@nestjs/swagger';
import { Request, Response } from 'express';
import { ConfigService } from '@nestjs/config';
import { AuthService } from './auth.service';
import { AuthCredentialsDto } from './dto/auth-credentials.dto';

@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) {}
constructor(
private authService: AuthService,
private configService: ConfigService,
) {}

@ApiOperation({ summary: '회원 가입 API' })
@Post('/signup')
Expand All @@ -24,16 +31,56 @@ export class AuthController {

@ApiOperation({ summary: '로그인 API' })
@Post('/login')
loginWithCredentials(
async loginWithCredentials(
@Body(ValidationPipe) authCredentialsDto: AuthCredentialsDto,
@Res() res: Response,
) {
return this.authService.loginUser(authCredentialsDto);
const { accessToken, refreshToken } =
await this.authService.loginUser(authCredentialsDto);

res.cookie('refreshToken', refreshToken, { httpOnly: true });
res.cookie('isRefreshToken', true, { httpOnly: true });
return res.status(200).json({ accessToken });
}

@ApiOperation({ summary: 'Token 인증 테스트 API' })
@Get('/test')
@UseGuards(AuthGuard())
@UseGuards(AuthGuard('jwt'))
test(@Req() req: Request) {
return req;
}

@ApiOperation({ summary: 'Kakao 로그인 API' })
@Get('/kakao')
@UseGuards(AuthGuard('kakao'))
async kakaoLogin(
@Body() authCredentialsDto: AuthCredentialsDto,
@Res() res: Response,
) {
const { accessToken, refreshToken } =
await this.authService.kakaoLoginUser(authCredentialsDto);

res.cookie('refreshToken', refreshToken, { httpOnly: true });
res.cookie('isRefreshToken', true, { httpOnly: true });
return res.status(200).json({ accessToken });
}

@ApiOperation({ summary: 'Refresh Token 요청 API' })
@Get('/refresh')
async refresh(@Req() req: Request, @Res() res: Response) {
if (
typeof req.cookies.refreshToken !== 'string' ||
typeof req.cookies.accessToken !== 'string'
) {
throw new UnauthorizedException('Invalid refresh token');
}

const { refreshToken } = req.cookies;

const newAccessToken = await this.authService.refreshToken(refreshToken);

res.cookie('refreshToken', refreshToken, { httpOnly: true });
res.cookie('isRefreshToken', true, { httpOnly: true });
return res.status(200).json({ accessToken: newAccessToken });
}
}
21 changes: 14 additions & 7 deletions BE/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,32 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { User } from './user.entity';
import { UserRepository } from './user.repository';
import { JwtStrategy } from './jwt.strategy';
import { JwtStrategy } from './strategy/jwt.strategy';
import { KakaoStrategy } from './strategy/kakao.strategy';

@Module({
imports: [
TypeOrmModule.forFeature([User]),
ConfigModule,
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.register({
secret: 'Juga16',
signOptions: {
expiresIn: 3600,
},
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
secret: configService.get<string>('JWT_SECRET'),
signOptions: {
expiresIn: configService.get<string>('JWT_ACCESS_EXPIRATION_TIME'),
},
}),
inject: [ConfigService],
}),
],
controllers: [AuthController],
providers: [AuthService, UserRepository, JwtStrategy],
providers: [AuthService, UserRepository, JwtStrategy, KakaoStrategy],
exports: [JwtStrategy, PassportModule],
})
export class AuthModule {}
Loading

0 comments on commit 3e0df74

Please sign in to comment.