Skip to content

Commit

Permalink
Merge pull request #63 from LocalMingle/dev
Browse files Browse the repository at this point in the history
[dev -> main] 희용, 에릭 작업 내용 merge
  • Loading branch information
erickimme authored Oct 23, 2023
2 parents 1d19b69 + 6a816da commit 440af29
Show file tree
Hide file tree
Showing 17 changed files with 224 additions and 78 deletions.
23 changes: 22 additions & 1 deletion package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"prisma": "^5.4.2",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1",
"swagger-ui-express": "^5.0.0"
"swagger-ui-express": "^5.0.0",
"ws": "^8.14.2"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
Expand Down
10 changes: 0 additions & 10 deletions src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,9 @@ export class AuthController {
// 엑세스 토큰을 HTTP 응답 헤더에 추가
res.header('accessToken', accessToken);

// 리프레시 토큰을 쿠키로 설정하여 클라이언트에게 전달
// httpOnly : javascript 로 쿠키에 접근 할 수 없는 옵션
// secure : true 일 시 https 연결에서만 전송된다.

// 리프레시 토큰을 HTTP 응답 헤더에 추가
res.header('refreshToken', refreshToken);

res.status(200).json({ userId }); // 클라이언트에게 JSON 응답을 보냄

//res.cookie('refreshToken', refreshToken, { httpOnly: true, secure: false });

// 액세스 토큰을 클라이언트에게 JSON 응답으로 반환 (Response body 에 전송)
//res.status(200).json({ accessToken }); // 클라이언트에게 JSON 응답을 보냄
}

// 리프레시 토큰을 사용하여 엑세스 토큰 재발급을 위한 엔드포인트 추가
Expand Down
4 changes: 2 additions & 2 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import { JwtAccessStrategy } from './strategies/jwt-access.strategy';
import { UsersService } from 'src/users/users.service';
import { JwtKakaoStrategy } from './strategies/jwt-social-kakao.strategy';
import { JwtGoogleStrategy } from './strategies/jwt-social-google.strategy';
//import { JwtRefreshStrategy } from './strategies/jwt-refresh.strategy';

export const jwtSecret = process.env.JWT_SECRET;
@Module({
imports: [PrismaModule, PassportModule, UsersModule, JwtModule.register({})],
controllers: [AuthController],
providers: [
AuthService,
JwtAccessStrategy,
AuthService,
UsersService,
JwtAccessStrategy,
JwtKakaoStrategy,
JwtNaverStrategy,
JwtGoogleStrategy,
Expand Down
60 changes: 36 additions & 24 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ export class AuthService {
// 리팩토링 시 res 빼도 작동하는지 테스트
accessToken: string;
refreshToken: string;

//user: User; // User 정보를 반환하기 위한 타입
userId: number; // userId만 반환
}> {
// 1. 이메일이 일치하는 유저를 DB에서 찾기
Expand All @@ -31,12 +29,16 @@ export class AuthService {
// 2. 일치하는 유저가 없으면 에러
if (!user) throw new NotFoundException('이메일이 없습니다.');

// 2-1. 사용자가 삭제되지 않았는지 확인 (deletedAt가 null이어야 함)
if (user.deletedAt !== null) {
throw new UnauthorizedException('사용자가 삭제되었습니다.');
}

// 3. 일치하는 유저는 있지만 비밀번호가 틀렸다면 에러
const isAuth = await bcrypt.compare(password, user.password);
if (!isAuth)
throw new UnauthorizedException('비밀번호가 일치하지 않습니다.');

// const isdeletedAt
// 4. 리프레시 토큰 생성
const refreshToken = this.setRefreshToken({ user, res });

Expand All @@ -51,11 +53,6 @@ export class AuthService {
},
});

//Authorization로 보내도록 결정되면 이렇게 수정(피드백 받으면 좋을 내용)
// res.header('Authorization', `Bearer ${accessToken}`);
// res.header('RefreshToken', refreshToken);

//TODO : user값 대신 userId값만 넘어가게 수정해야함 ()
return { accessToken, refreshToken, userId: user.userId }; //리턴값
}

Expand All @@ -65,11 +62,7 @@ export class AuthService {
{ secret: process.env.JWT_ACCESS_KEY, expiresIn: '36000s' }
);

res.header('accessToken', accessToken); // 클라이언트로 액세스 토큰을 반환
//res.header('Authorization', `Bearer ${accessToken}`); // 클라이언트로 액세스토큰을 Authorization 에 Bearer 로 반환
//console.log('엑세스 토큰 확인용 로그', user);
return accessToken;
// return res.header(accessToken);
}

setRefreshToken({ user, res }): string {
Expand All @@ -79,10 +72,7 @@ export class AuthService {
{ secret: process.env.JWT_REFRESH_KEY, expiresIn: '2w' }
);

res.header('refreshToken', refreshToken); // 클라이언트로 리프레시 토큰을 반환
//console.log('리프레시 토큰 확인용 로그', user);
return refreshToken;
// return res.header(refreshToken);
}

async refreshAccessToken(refreshToken: string): Promise<string> {
Expand All @@ -92,8 +82,10 @@ export class AuthService {
});

// 리프레시 토큰이 유효하다면 새로운 액세스 토큰을 발급
const userId = decodedToken.sub; // 추출된 사용자 ID

const newAccessToken = await this.getAccessToken({
user: decodedToken,
user: { userId }, // 사용자 ID를 전달
res: null,
});

Expand All @@ -117,7 +109,6 @@ export class AuthService {
confirmPassword: req.user.password, // 비밀번호를 해싱하여 저장
intro: req.user.intro,
profileImg: req.user.profileImg,
// 다른 필드도 설정해야 할 수 있음
};
// console.log('소셜 로그인 회원가입 : ', createUser); // createUser 정보를 콘솔에 출력
user = await this.usersService.create(createUser);
Expand All @@ -134,19 +125,40 @@ export class AuthService {
},
});

//Authorization로 보내도록 결정되면 이렇게 수정(피드백 받으면 좋을 내용)
//res.header('Authorization', `Bearer ${accessToken}`);
//res.header('RefreshToken', refreshToken);

// res.header(accessToken);
// res.header(refreshToken);
//토큰 요청헤더로 보내는 코드
// res.header('accessToken', accessToken);
// res.header('refreshToken', refreshToken);
res.header('userId', user.userId);

//토큰 쿠키로 보내는 코드드
// res.cookie('accessToken', accessToken, {
// httpOnly: false, // 배포시에 true
// sameSite: 'none',
// secure: false, // 배포시에 true
// });

// res.cookie('refreshToken', refreshToken, {
// httpOnly: false, // 배포시에 true
// sameSite: 'none',
// secure: false, // 배포시에 true
// });

console.log('로컬 엑세스 토큰', accessToken);
console.log('로컬 리프레시 토큰', refreshToken);
console.log(user.userId);

// 리다이렉션
res.redirect('https://www.totobon6125.store'); // 메인페이지 url 을 입력해야합니다.
res.redirect(
`http://localhost:5500?accessToken=${encodeURIComponent(
accessToken
)}&refreshToken=${encodeURIComponent(
refreshToken
)}&userId=${encodeURIComponent(user.userId)}`
);
// 현재 : 파람스로 AT,RT userId전달 // https 로 배포되면 cookie로 바꿔야함
// `http://localhost:5500?userId=${user.userId}`
//https://www.totobon6125.store/
// https://www.totobon6125.store?userId=${user.userId}
//http://localhost:5173/
//http://127.0.0.1:5500
return { accessToken, refreshToken, userId: user.userId };
Expand Down
3 changes: 1 addition & 2 deletions src/auth/guards/jwt-auth.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

// export class JwtAuthGuard extends AuthGuard('jwt') {}
export class JwtAccessAuthGuard extends AuthGuard('access') {}
export class JwtRefreshAuthGuard extends AuthGuard('refresh') {}
2 changes: 1 addition & 1 deletion src/auth/strategies/jwt-access.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { UsersService } from 'src/users/users.service';

//1. 비밀번호 검증
//2. 만료시간 검증
export class JwtAccessStrategy extends PassportStrategy(Strategy, 'jwt') {
export class JwtAccessStrategy extends PassportStrategy(Strategy, 'access') {
constructor(private usersService: UsersService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), //엑세스 토큰
Expand Down
48 changes: 36 additions & 12 deletions src/auth/strategies/jwt-refresh.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
// import { PassportStrategy } from '@nestjs/passport';
// import { Strategy } from 'passport-jwt';
// import { Strategy, ExtractJwt } from 'passport-jwt';
// import { Injectable, UnauthorizedException, Request } from '@nestjs/common';
// import { JwtService } from '@nestjs/jwt';
// import { UsersService } from '../../users/users.service';

// @Injectable()
// export class JwtRefreshStrategy extends PassportStrategy(Strategy, 'refresh') {
// constructor() {
// constructor(
// private jwtService: JwtService,
// private usersService: UsersService
// ) {
// super({
// jwtFromRequest: (req) => {
// const cookie = req.headers.cookie;
// const refreshToken = cookie.replace('refreshToken=', '');
// return refreshToken;
// },
// jwtFromRequest: ExtractJwt.fromHeader('refreshtoken'), // 헤더에서 리프레시 토큰을 추출
// secretOrKey: process.env.JWT_REFRESH_KEY,
// });
// }

// validate(payload) {
// return {
// email: payload.email,
// id: payload.sub,
// };
// async validate(payload: any, @Request() req: any) {
// // 'refreshtoken' 헤더에서 refreshToken을 추출
// const refreshToken = req.headers.refreshtoken as string;
// console.log('리프레시토큰 확인', refreshToken);
// if (!refreshToken) {
// throw new UnauthorizedException('Refresh token not provided');
// }

// try {
// // 리프레시 토큰의 유효성을 검증
// const decodedToken = this.jwtService.verify(refreshToken, {
// secret: process.env.JWT_REFRESH_KEY,
// });

// // 유효한 사용자를 찾을 때 사용자 서비스를 활용
// const user = await this.usersService.findById(decodedToken.sub);

// if (!user) {
// throw new UnauthorizedException('Invalid token');
// }

// // 사용자 정보를 반환
// return { email: user.email, id: user.userId };
// } catch (error) {
// throw new UnauthorizedException('Invalid token');
// }
// }
// }
2 changes: 1 addition & 1 deletion src/auth/strategies/jwt-social-kakao.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class JwtKakaoStrategy extends PassportStrategy(Strategy, 'kakao') {
console.log('카카오에서 주는 accessToken:' + accessToken);
console.log('카카오에서 주는 refreshToken:' + refreshToken);
console.log('카카오 프로필', profile);
//console.log(profile._json.kakao_account.email);
console.log(profile._json.kakao_account.email);

// 비밀번호 암호화
const hashedPassword = await bcrypt.hash(profile.id.toString(), 10);
Expand Down
12 changes: 6 additions & 6 deletions src/events/events.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
ApiBody,
} from '@nestjs/swagger';
import { EventEntity } from './entities/event.entity';
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
import { JwtAccessAuthGuard } from 'src/auth/guards/jwt-auth.guard';
import { User } from '@prisma/client';
import { FileInterceptor } from '@nestjs/platform-express';
import { AwsS3Service } from 'src/aws/aws.s3';
Expand All @@ -47,7 +47,7 @@ export class EventsController {

// 이벤트 생성
@Post()
@UseGuards(JwtAuthGuard) // passport를 사용하여 인증 확인
@UseGuards(JwtAccessAuthGuard) // passport를 사용하여 인증 확인
@ApiBearerAuth() // Swagger 문서에 Bearer 토큰 인증 추가
@ApiOperation({ summary: '호스트로 Event 생성' })
@ApiCreatedResponse({ type: EventEntity })
Expand All @@ -59,7 +59,7 @@ export class EventsController {

// 이벤트 이미지 업로드
@Post('upload')
@UseGuards(JwtAuthGuard) // passport를 사용하여 인증 확인
@UseGuards(JwtAccessAuthGuard) // passport를 사용하여 인증 확인
@ApiBearerAuth() // Swagger 문서에 Bearer 토큰 인증 추가
@ApiOperation({ summary: 'Event 이미지 업로드' })
@ApiConsumes('multipart/form-data')
Expand Down Expand Up @@ -133,7 +133,7 @@ export class EventsController {

// 이벤트 참가 신청
@Put(':eventId/join')
@UseGuards(JwtAuthGuard) // passport를 사용하여 인증 확인
@UseGuards(JwtAccessAuthGuard) // passport를 사용하여 인증 확인
@ApiBearerAuth() // Swagger 문서에 Bearer 토큰 인증 추가
@ApiOperation({ summary: 'Guest로서 Event 참가신청' })
@ApiCreatedResponse({ description: `모임 참석 신청 / 취소` })
Expand Down Expand Up @@ -186,7 +186,7 @@ export class EventsController {

// 관심있는 이벤트 북마크 추가
@Post(':eventId/bookmark')
@UseGuards(JwtAuthGuard)
@UseGuards(JwtAccessAuthGuard)
@ApiBearerAuth()
@ApiOperation({ summary: 'Event 북마크 추가' })
async addBookmark(
Expand All @@ -199,7 +199,7 @@ export class EventsController {

// 관심있는 이벤트 북마크 제거
@Delete(':eventId/bookmark')
@UseGuards(JwtAuthGuard)
@UseGuards(JwtAccessAuthGuard)
@ApiBearerAuth()
@ApiOperation({ summary: 'Event 북마크 제거' })
async removeBookmark(
Expand Down
2 changes: 2 additions & 0 deletions src/events/events.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export class EventsService {
},
});



return event;
}

Expand Down
12 changes: 12 additions & 0 deletions src/mails/dto/verify-code.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { IsInt } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class VerifyCodeDto {
@ApiProperty()
@IsInt()
@ApiProperty({
description: 'code',
example: '12345',
})
code: number;
}
Loading

0 comments on commit 440af29

Please sign in to comment.