Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[FEAT] 로그아웃 구현 및 redis를 통한 임시 유저 저장 구현 #25

Merged
merged 37 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
ceda480
[DOCS] PR 템플릿 수정
mikekks Jan 26, 2024
7aa8289
[REFACTOR] redis 저장으로 로직 변경
mikekks Jan 26, 2024
111fcea
[MOVE] 이메일 관련 에러 코드 UniversityExceptionType으로 이동
mikekks Jan 26, 2024
590a3ee
[DEL] VO 통합으로 인한 삭제
mikekks Jan 26, 2024
dfcf17f
[DEL] VO 통합으로 인한 삭제
mikekks Jan 26, 2024
2160512
[DEL] 필요없는 코드 삭제
mikekks Jan 26, 2024
1014feb
[FEAT] redis에 저장할 임시 유저 정의
mikekks Jan 26, 2024
de8c777
[FIX] 요청받을 데이터 수정
mikekks Jan 26, 2024
35b4e14
[DEL] Dto명 변경으로 인한 삭제
mikekks Jan 26, 2024
d162139
[CHORE] 일부 필요없는 코드 삭제 및 데이터 길이 수정
mikekks Jan 26, 2024
34e2b77
[REFACTOR] AuthService으로 의존성 정리
mikekks Jan 26, 2024
a3143df
[FEAT] redis관련 로직 구현
mikekks Jan 26, 2024
d416cb5
[MOVE] 파일 위치 변경
mikekks Jan 26, 2024
7733ab7
[RENAME] 파일 이름 변경
mikekks Jan 26, 2024
7cb2e29
[RENAME] 파일 이름 변경
mikekks Jan 26, 2024
4c35ea8
[FEAT] 로그아웃 구현
mikekks Jan 26, 2024
c5cceaa
[ADD] 로그아웃 Dto 추가
mikekks Jan 26, 2024
af7aed3
[REFACTOR] 메일 서비스의 레포지토리 의존성 제거를 통한 개선
mikekks Jan 26, 2024
2ba6aee
[FEAT] redis, university 레포지토리 추가
mikekks Jan 26, 2024
279d614
[ADD] secondary index TimeToLive 적용을 위한 코드 추가
mikekks Jan 26, 2024
6ca8873
[ADD] RedisException 추가
mikekks Jan 26, 2024
b53babe
[ADD] RedisExceptionType enum 추가
mikekks Jan 26, 2024
615971c
[FEAT] 임시 유저 저장을 위한 Redis 레포지토리 구현
mikekks Jan 26, 2024
0b236f1
[RENAME] 파일 이름 변경
mikekks Jan 26, 2024
ce84f8d
[ADD] Id로 찾는 메서드 추가
mikekks Jan 26, 2024
7268273
[FEAT] Id로 찾는 메서드 구현
mikekks Jan 26, 2024
29cf1a9
[DEL] 필요없는 의존성 제거
mikekks Jan 26, 2024
8a6f2f6
[DEL] 필요없는 코드 제거
mikekks Jan 26, 2024
747bcb5
[CHORE] 로그아웃 관련 코드 리뷰 반영
mikekks Jan 30, 2024
925607e
[CHORE] 함수 이름 변경
mikekks Jan 30, 2024
96f0474
[CHORE] 함수 이름 변경
mikekks Jan 30, 2024
038848d
[CHORE] 변수 이름 변경
mikekks Jan 30, 2024
b040cef
[CHORE] TTL 시간 변경
mikekks Jan 30, 2024
7a1ab70
[ADD] 매직리터럴 상수로 추가
mikekks Jan 30, 2024
f9a4f43
[DOCS] 스웨거 API 문서 작성
mikekks Jan 30, 2024
10ffe1d
[DOCS] 스웨거 API 문서 수정
mikekks Jan 30, 2024
7383c5c
[DOCS] 스웨거 Dto 문서 추가
mikekks Jan 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions .github/pull_request_template.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳굳! 좋은 것 같아요!

Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
# 구현 내용/방법
## 📝 PR 타입
- [ ] 기능 추가
- [ ] 기능 수정
- [ ] 기능 삭제
- [ ] 리팩토링
- [ ] 의존성, 환경 변수, 빌드 관련 코드 업데이트

> 간단하게 구현한 내용과 방법에 대한 설명
>
-
-
## 📝 반영 브랜치
<!-- feat/#issue -> dev와 같이 반영 브랜치를 표시합니다 -->
<!-- closed #issue로 merge되면 issue가 자동으로 close되게 해줍니다 -->
- feat/
- closed

# 리뷰 필요
## 📝 변경 사항
<!-- 로그인 시, 구글 소셜 로그인 기능을 추가했습니다. 와 같이 작성합니다 -->

> 나중에 다시 고민해야할 내용이 있는 내용
>
> 없을 경우 작성 X

> 있을 경우 작성 후 이슈 남기고 해당 PR 링크
>
-
-
## 📝 테스트 결과
<!-- local에서 postman으로 요청한 결과를 첨부합니다, postman을 사용하지 않으면 관련 화면 캡쳐 -->

close

## 📝 To Reviewer
<!-- review 받고 싶은 point를 작성합니다 -->
74 changes: 37 additions & 37 deletions src/main/java/synk/meeteam/domain/auth/api/AuthController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package synk.meeteam.domain.auth.api;

import static synk.meeteam.domain.auth.exception.AuthExceptionType.INVALID_MAIL_REGEX;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
Expand All @@ -15,20 +14,20 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import synk.meeteam.domain.auth.api.dto.request.UserAuthRequestDTO;
import synk.meeteam.domain.auth.api.dto.request.User#RequestDTO;
import synk.meeteam.domain.auth.api.dto.response.UserAuthResponseDTO;
import synk.meeteam.domain.auth.api.dto.response.UserReissueResponseDTO;
import synk.meeteam.domain.auth.api.dto.response.User#ResponseDTO;
import synk.meeteam.domain.auth.exception.AuthException;
import synk.meeteam.domain.auth.dto.request.AuthUserRequestDto;
import synk.meeteam.domain.auth.dto.request.#UserRequestDto;
import synk.meeteam.domain.auth.dto.request.VerifyUserRequestDto;
import synk.meeteam.domain.auth.dto.response.AuthUserResponseDto;
import synk.meeteam.domain.auth.dto.response.LogoutUserResponseDto;
import synk.meeteam.domain.auth.dto.response.ReissueUserResponseDto;
import synk.meeteam.domain.auth.dto.response.#UserResponseDto;
import synk.meeteam.domain.auth.service.AuthServiceProvider;
import synk.meeteam.domain.auth.service.vo.User#VO;
import synk.meeteam.domain.university.service.UniversityService;
import synk.meeteam.domain.user.entity.User;
import synk.meeteam.domain.user.entity.UserVO;
import synk.meeteam.domain.user.entity.enums.Role;
import synk.meeteam.domain.user.repository.UserRepository;
import synk.meeteam.domain.user.service.UserService;
import synk.meeteam.infra.mail.MailService;
import synk.meeteam.infra.oauth.service.vo.enums.AuthType;
Expand All @@ -43,7 +42,6 @@ public class AuthController {
private final JwtService jwtService;
private final MailService mailService;
private final UniversityService universityService;
private final UserRepository userRepository;
private final UserService userService;

@Value("${spring.security.oauth2.client.naver.client-id}")
Expand All @@ -52,57 +50,59 @@ public class AuthController {
private String redirectUri;

@PostMapping("/social/#")
public ResponseEntity<UserAuthResponseDTO> login(
public ResponseEntity<AuthUserResponseDto> login(
@RequestHeader(value = "authorization-code") final String authorizationCode,
@RequestBody @Valid final
UserAuthRequestDTO request, HttpServletResponse response) {
AuthUserRequestDto requestDto) {

User#VO vo = authServiceProvider.getAuthService(request.platformType())
.saveUserOrLogin(authorizationCode, request);
User#VO vo = authServiceProvider.getAuthService(requestDto.platformType())
.saveUserOrLogin(authorizationCode, requestDto);

if (vo.role() == Role.GUEST) {
return ResponseEntity.ok(UserAuthResponseDTO
return ResponseEntity.ok(AuthUserResponseDto
.of(vo.platformId(), vo.authType(), vo.name(), vo.role(), null, null));
}

UserAuthResponseDTO responseDTO = jwtService.issueToken(vo);
if (responseDTO.authType().equals(AuthType.SIGN_UP)) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(responseDTO);
}
AuthUserResponseDto responseDTO = jwtService.issueToken(vo);
return ResponseEntity.ok(responseDTO);
}

@PostMapping("/social/sign-up")
public ResponseEntity<User#ResponseDTO> #(
@RequestBody @Valid User#RequestDTO requestDTO
public ResponseEntity<#UserResponseDto> #(
@RequestBody @Valid #UserRequestDto requestDto
) {
if (!universityService.isValidRegex(requestDTO.universityName(), requestDTO.email())){
throw new AuthException(INVALID_MAIL_REGEX);
}
Long universityId = universityService.getUniversityId(requestDto.universityName(), requestDto.departmentName(),
requestDto.email());

userService.updateUniversityInfo(requestDTO);
mailService.sendMail(requestDTO);
authServiceProvider.getAuthService(requestDto.platformType()).updateUniversityInfo(requestDto, universityId);
mailService.sendMail(requestDto, requestDto.platformId());

return ResponseEntity.ok(User#ResponseDTO.of(requestDTO.platformId()));
return ResponseEntity.ok(#UserResponseDto.of(requestDto.platformId()));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

곰곰히 생각해보니, 해당 부분의 기능은 이메일을 보내는 부분이라는 생각이 듭니다. 함수명을 변경하는것은 어떻게 생각하시나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 emailVerify와 바꾸는게 좋을 것 같습니다!

Copy link
Member

@Goder-0 Goder-0 Jan 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사용자의 일부 정보를 입력받고 임시 유저도 생성하는 역할도 하고 있으니,
createTempUserAndSendEmail을 좀 줄여서 적용하면 어떨까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넹 좋아요


@GetMapping("/email-verify")
public ResponseEntity<UserAuthResponseDTO> verify(
@RequestParam String emailCode) {
@PostMapping("/email-verify")
public ResponseEntity<AuthUserResponseDto> verify(
@RequestBody @Valid VerifyUserRequestDto requestDto) {

UserVO userVO = mailService.verify(requestDto.emailCode());
User user = authServiceProvider.getAuthService(userVO.getPlatformType())
.createSocialUser(userVO, requestDto.nickName());

User user = mailService.verify(emailCode);
User#VO vo = User#VO.of(user, user.getPlatformType(), user.getRole(), AuthType.SIGN_UP);
UserAuthResponseDTO responseDTO = jwtService.issueToken(vo);
AuthUserResponseDto responseDTO = jwtService.issueToken(vo);

return ResponseEntity.status(HttpStatus.CREATED).body(responseDTO);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sign-up과 같은 맥락으로 해당 코드는 이메일 검증보다, 회원가입의 역할에 좀더 가깝다고 생각합니다.


@PostMapping("/reissue")
public ResponseEntity<UserReissueResponseDTO> reissue(HttpServletRequest request,
HttpServletResponse response) {
UserReissueResponseDTO userReissueResponseDTO = jwtService.reissueToken(request, response);
return ResponseEntity.ok().body(userReissueResponseDTO);
public ResponseEntity<ReissueUserResponseDto> reissue(HttpServletRequest request) {
ReissueUserResponseDto reissueUserResponseDto = jwtService.reissueToken(request);
return ResponseEntity.ok().body(reissueUserResponseDto);
}

@PostMapping("/logout")
public ResponseEntity<LogoutUserResponseDto> logout(HttpServletRequest request) {
return ResponseEntity.ok(jwtService.logout(request));
}


Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package synk.meeteam.domain.auth.api.dto.request;
package synk.meeteam.domain.auth.dto.request;

import jakarta.validation.constraints.NotNull;
import synk.meeteam.domain.user.entity.enums.PlatformType;

public record UserAuthRequestDTO(@NotNull PlatformType platformType) {
public record AuthUserRequestDto(@NotNull PlatformType platformType) {
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package synk.meeteam.domain.auth.api.dto.request;
package synk.meeteam.domain.auth.dto.request;

import jakarta.validation.constraints.NotNull;
import synk.meeteam.domain.user.entity.enums.PlatformType;

public record User#RequestDTO(
public record #UserRequestDto(
@NotNull String platformId,
@NotNull PlatformType platformType,
@NotNull String email,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package synk.meeteam.domain.auth.dto.request;

import jakarta.validation.constraints.NotNull;

public record VerifyUserRequestDto(
@NotNull String emailCode,
@NotNull String nickName

) {
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package synk.meeteam.domain.auth.api.dto.response;
package synk.meeteam.domain.auth.dto.response;

import jakarta.validation.constraints.NotNull;
import synk.meeteam.domain.user.entity.enums.Role;
import synk.meeteam.infra.oauth.service.vo.enums.AuthType;

public record UserAuthResponseDTO(@NotNull String platformId, @NotNull AuthType authType, @NotNull String userName,
public record AuthUserResponseDto(@NotNull String platformId, @NotNull AuthType authType, @NotNull String userName,
@NotNull Role role, String accessToken, String refreshToken) {
public static UserAuthResponseDTO of(String platformId, AuthType authType, String userName, Role role,
public static AuthUserResponseDto of(String platformId, AuthType authType, String userName, Role role,
String accessToken, String refreshToken) {
return new UserAuthResponseDTO(platformId, authType, userName, role, accessToken, refreshToken);
return new AuthUserResponseDto(platformId, authType, userName, role, accessToken, refreshToken);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DTO에서 Dto로 수정하셨네요!
그런데 of 함수가 정의된 일부 record dto가 보이는데, 혹시 어떠한 의도로 작성하신걸까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

팩토리 메서드를 의도한거였는데 조금 더 자세히 설명주실 수 있을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음 제가 원하는건 팩토리 메서드였고, 그렇기에 record 클래스에 생성 역할을 위임하고 싶었습니다! service 로직에서 new를 사용하는 것보다 유지보수 측면에서 좋다고 생각했습니다!
또한, 컨벤션으로 많이 사용하는 것으로 알고있기 때문에 사용했었습니다!

혹시 생성자를 사용하는 다른 의도나 이유가 있으신가요?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하! 이해했습니다.
팩토리 메소드를 의도했다는 의미를 이해하지 못하고 있었네요!
정적 팩토리 메소드 네이밍 규칙이 있다는 사실도 처음알았습니다 ㅋㅋ
이거 같이 적용하면서 사용하도록 하죠!
관련 링크

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package synk.meeteam.domain.auth.dto.response;

import jakarta.validation.constraints.NotNull;

public record LogoutUserResponseDto(
@NotNull String PlatformId
) {
public static LogoutUserResponseDto of(String platformId) {
return new LogoutUserResponseDto(platformId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package synk.meeteam.domain.auth.dto.response;

import jakarta.validation.constraints.NotNull;

public record ReissueUserResponseDto(@NotNull String platformId, @NotNull String accessToken, @NotNull String refreshToken) {
public static ReissueUserResponseDto of(String platformId, String accessToken,
String refreshToken) {
return new ReissueUserResponseDto(platformId, accessToken, refreshToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package synk.meeteam.domain.auth.dto.response;

import jakarta.validation.constraints.NotNull;

public record #UserResponseDto(
@NotNull String platformId
) {
public static #UserResponseDto of(String platformId) {
return new #UserResponseDto(platformId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ public enum AuthExceptionType implements ExceptionType {
*/

NOT_FOUND_USER(HttpStatus.NOT_FOUND, "유효한 유저를 찾지 못했습니다."),
NOT_FOUND_REFRESH_TOKEN(HttpStatus.NOT_FOUND, "유효한 리프레시 토큰을 찾지 못했습니다."),
NOT_FOUND_EMAIL_CODE(HttpStatus.NOT_FOUND, "유효한 이메일 코드를 찾지 못했습니다."),
NOT_FOUND_UNIVERSITY_AND_DEPARTMENT(HttpStatus.NOT_FOUND, "유효한 학교명 및 학과명을 찾지 못했습니다.");


NOT_FOUND_REFRESH_TOKEN(HttpStatus.NOT_FOUND, "유효한 리프레시 토큰을 찾지 못했습니다.");
Comment on lines 33 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

에러 코드의 위치를 옮기셨군요!


private final HttpStatus status;
private final String message;
Expand Down
Loading
Loading