-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[REFACTOR/#174] MemberService 로직 리팩 및 회원가입 테스트 코드 작성 #176
Merged
Merged
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
60f549b
[refactor] Memberservice 중복되는 로직 메서드로 분리
JungYoonShin d5e1ec6
[Test] MemberRepository 통합테스트
JungYoonShin a441dbe
[Merge] 충돌 해결
JungYoonShin 04180b7
[refactor] 필요없는 코드 삭제
JungYoonShin 7ff706d
[refactor] Image 기본 생성자 접근제어자 추가
JungYoonShin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
src/main/java/com/favoriteplace/app/member/controller/dto/MemberSignUpReqDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.favoriteplace.app.member.controller.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
|
||
public record MemberSignUpReqDto( | ||
@NotBlank(message = "닉네임은 필수값입니다.") | ||
String nickname, | ||
String email, | ||
String password, | ||
Boolean snsAllow, | ||
String introduction | ||
) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
src/main/java/com/favoriteplace/app/member/repository/MemberRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,17 @@ | ||
package com.favoriteplace.app.member.repository; | ||
|
||
import com.favoriteplace.app.member.domain.Member; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface MemberRepository extends JpaRepository<Member, Long> { | ||
|
||
Optional<Member> findByEmail(String email); | ||
boolean existsById(Long id); | ||
|
||
List<Member> findAllByEmail(String email); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,30 @@ | ||
package com.favoriteplace.app.member.service; | ||
|
||
import static com.favoriteplace.global.exception.ErrorCode.NOT_SIGNUP_WITH_KAKAO; | ||
import static com.favoriteplace.global.exception.ErrorCode.TOKEN_NOT_VALID; | ||
import static com.favoriteplace.global.exception.ErrorCode.USER_ALREADY_EXISTS; | ||
import static com.favoriteplace.global.exception.ErrorCode.USER_NOT_FOUND; | ||
|
||
import com.favoriteplace.app.member.controller.dto.MemberSignUpReqDto; | ||
import com.favoriteplace.app.member.controller.dto.TokenInfoDto; | ||
import com.favoriteplace.app.member.domain.Member; | ||
import com.favoriteplace.app.item.domain.Item; | ||
import com.favoriteplace.app.item.repository.ItemRepository; | ||
import com.favoriteplace.app.member.controller.dto.AuthKakaoLoginDto; | ||
import com.favoriteplace.app.member.controller.dto.UserInfoResponseDto; | ||
import com.favoriteplace.app.member.controller.dto.KaKaoSignUpRequestDto; | ||
import com.favoriteplace.app.member.controller.dto.MemberDto; | ||
import com.favoriteplace.app.member.controller.dto.TokenInfoDto; | ||
import com.favoriteplace.app.member.controller.dto.UserInfoResponseDto; | ||
import com.favoriteplace.app.member.domain.Member; | ||
import com.favoriteplace.app.member.controller.dto.MemberDto.EmailDuplicateResDto; | ||
import com.favoriteplace.app.member.controller.dto.MemberDto.EmailSendReqDto; | ||
import com.favoriteplace.app.item.repository.ItemRepository; | ||
import com.favoriteplace.app.member.repository.MemberRepository; | ||
import com.favoriteplace.global.exception.RestApiException; | ||
import com.favoriteplace.global.s3Image.AmazonS3ImageManager; | ||
import com.favoriteplace.global.auth.kakao.KakaoClient; | ||
import com.favoriteplace.global.auth.provider.JwtTokenProvider; | ||
import com.favoriteplace.global.util.SecurityUtil; | ||
import com.favoriteplace.global.exception.RestApiException; | ||
import com.favoriteplace.global.s3Image.AmazonS3ImageManager; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.security.core.Authentication; | ||
|
@@ -36,26 +36,23 @@ | |
@Service | ||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class MemberService { | ||
|
||
private final MemberRepository memberRepository; | ||
private final PasswordEncoder passwordEncoder; | ||
private final JwtTokenProvider jwtTokenProvider; | ||
private final SecurityUtil securityUtil; | ||
private final AmazonS3ImageManager amazonS3ImageManager; | ||
private final ItemRepository itemRepository; | ||
private final RedisTemplate redisTemplate; | ||
private final KakaoClient kakaoClient; | ||
|
||
public TokenInfoDto kakaoLogin(final String token) { | ||
AuthKakaoLoginDto userInfo = kakaoClient.getUserInfo(token); | ||
String userEmail = getUserEmailFromKakao(token); | ||
|
||
// 최초 로그인이라면 회원가입 API로 통신하도록 | ||
Member member = memberRepository.findByEmail(userInfo.kakaoAccount().email()) | ||
.orElseThrow(() -> new RestApiException(NOT_SIGNUP_WITH_KAKAO)); | ||
Member member = findMember(userEmail); | ||
|
||
return jwtTokenProvider.generateToken(userInfo.kakaoAccount().email()); | ||
return issueToken(userEmail); | ||
} | ||
|
||
@Transactional | ||
|
@@ -65,24 +62,22 @@ public MemberDto.MemberSignUpResDto kakaoSignUp( | |
final List<MultipartFile> images | ||
) throws IOException { | ||
|
||
String userEmail = kakaoClient.getUserInfo(token).kakaoAccount().email(); | ||
String userEmail = getUserEmailFromKakao(token); | ||
|
||
memberRepository.findByEmail(userEmail) | ||
.ifPresent(a -> { | ||
throw new RestApiException(USER_ALREADY_EXISTS); | ||
}); | ||
|
||
String profileImageUrl = null; | ||
if (images != null && !images.get(0).isEmpty()) { | ||
profileImageUrl = uploadProfileImage(images.get(0)); | ||
} | ||
String profileImage = getProfileImageFromRequest(images); | ||
|
||
Item titleItem = itemRepository.findByName("새싹회원").get(); | ||
Item titleItem = getDefaultProfileItem(); | ||
|
||
Member member = memberSignUpReqDto.toEntity(profileImageUrl, titleItem, userEmail); | ||
memberRepository.save(member); | ||
Member member = saveUser(memberSignUpReqDto.nickname(), userEmail, | ||
memberSignUpReqDto.snsAllow(), memberSignUpReqDto.introduction(), | ||
profileImage, titleItem); | ||
|
||
TokenInfoDto tokenInfo = jwtTokenProvider.generateToken(userEmail); | ||
TokenInfoDto tokenInfo = issueToken(userEmail); | ||
member.updateRefreshToken(tokenInfo.refreshToken()); | ||
|
||
return MemberDto.MemberSignUpResDto.from(member, tokenInfo); | ||
|
@@ -91,30 +86,29 @@ public MemberDto.MemberSignUpResDto kakaoSignUp( | |
|
||
@Transactional | ||
public MemberDto.MemberSignUpResDto signup( | ||
final MemberDto.MemberSignUpReqDto memberSignUpReqDto, | ||
final MemberSignUpReqDto memberSignUpReqDto, | ||
final List<MultipartFile> images | ||
) throws IOException { | ||
|
||
memberRepository.findByEmail(memberSignUpReqDto.getEmail()) | ||
.ifPresent( | ||
existingMember -> { | ||
throw new RestApiException(USER_ALREADY_EXISTS); | ||
} | ||
); | ||
// memberRepository.findByEmail(memberSignUpReqDto.getEmail()) | ||
// .ifPresent( | ||
// existingMember -> { | ||
// throw new RestApiException(USER_ALREADY_EXISTS); | ||
// } | ||
// ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 사용하지 않는 코드라면 지워주세요!! |
||
|
||
String profileImageUrl = null; | ||
if (images != null && !images.get(0).isEmpty()) { | ||
profileImageUrl = uploadProfileImage(images.get(0)); | ||
} | ||
|
||
String password = passwordEncoder.encode(memberSignUpReqDto.getPassword()); | ||
String password = passwordEncoder.encode(memberSignUpReqDto.password()); | ||
|
||
Item titleItem = itemRepository.findByName("새싹회원").get(); | ||
Item titleItem = getDefaultProfileItem(); | ||
|
||
Member member = memberSignUpReqDto.toEntity(password, profileImageUrl, titleItem); | ||
memberRepository.save(member); | ||
String profileImage = getProfileImageFromRequest(images); | ||
|
||
TokenInfoDto tokenInfo = jwtTokenProvider.generateToken(member.getEmail()); | ||
Member member = saveUser(memberSignUpReqDto.nickname(), memberSignUpReqDto.email(), | ||
memberSignUpReqDto.snsAllow(), memberSignUpReqDto.introduction(), | ||
profileImage, titleItem); | ||
|
||
TokenInfoDto tokenInfo= issueToken(member.getEmail()); | ||
member.updateRefreshToken(tokenInfo.refreshToken()); | ||
|
||
return MemberDto.MemberSignUpResDto.from(member, tokenInfo); | ||
|
@@ -124,12 +118,11 @@ public String uploadProfileImage(MultipartFile profileImage) throws IOException | |
return amazonS3ImageManager.upload(profileImage).join(); | ||
} | ||
|
||
@Transactional | ||
public MemberDto.EmailDuplicateResDto emailDuplicateCheck(MemberDto.EmailSendReqDto emailSendReqDto) { | ||
public MemberDto.EmailDuplicateResDto emailDuplicateCheck(EmailSendReqDto emailSendReqDto) { | ||
String email = emailSendReqDto.getEmail(); | ||
Boolean isExists = memberRepository.findByEmail(email).isPresent(); | ||
|
||
return new MemberDto.EmailDuplicateResDto(isExists); | ||
return new EmailDuplicateResDto(isExists); | ||
} | ||
|
||
@Transactional | ||
|
@@ -140,7 +133,6 @@ public void setNewPassword(String email, String password) { | |
member.updatePassword(newPassword); | ||
} | ||
|
||
@Transactional | ||
public UserInfoResponseDto getUserInfo(Member member) { | ||
if (member != null) { | ||
return UserInfoResponseDto.of(member); | ||
|
@@ -149,25 +141,57 @@ public UserInfoResponseDto getUserInfo(Member member) { | |
} | ||
|
||
@Transactional | ||
public void logout(String token){ | ||
Authentication authentication = jwtTokenProvider.getAuthentication(token); | ||
public void logout(String accessToken) { | ||
/*1. Access Token 검증 */ | ||
if (!jwtTokenProvider.validateToken(accessToken)) { | ||
new RestApiException(TOKEN_NOT_VALID); | ||
} | ||
|
||
Authentication authentication = jwtTokenProvider.getAuthentication(accessToken); | ||
Member member = findMember(authentication.getName()); | ||
|
||
if (member.getRefreshToken() != null && !member.getRefreshToken().isEmpty()) { | ||
member.deleteRefreshToken(member.getRefreshToken()); | ||
} | ||
|
||
/* 해당 asscess token 유효시간을 계산해서 blacklist로 저장 */ | ||
Long expriation = jwtTokenProvider.getExpiration(token); | ||
log.info(String.valueOf(expriation)); | ||
Long expriation = jwtTokenProvider.getExpiration(accessToken); | ||
redisTemplate.opsForValue() | ||
.set(token, "logout", expriation, TimeUnit.MILLISECONDS); | ||
|
||
.set(accessToken, "logout", expriation, TimeUnit.MICROSECONDS); | ||
} | ||
|
||
public Member findMember(final String email) { | ||
private Member findMember(final String email) { | ||
return memberRepository.findByEmail(email) | ||
.orElseThrow(() -> new RestApiException(USER_NOT_FOUND)); | ||
} | ||
|
||
private String getUserEmailFromKakao(String token) { | ||
return kakaoClient.getUserInfo(token).kakaoAccount().email(); | ||
} | ||
|
||
private Item getDefaultProfileItem() { | ||
return itemRepository.findByName("새싹회원").get(); | ||
} | ||
|
||
private TokenInfoDto issueToken(String email) { | ||
return jwtTokenProvider.generateToken(email); | ||
} | ||
|
||
private Member saveUser( | ||
String nickname, String email, | ||
boolean snsAllow, String introduction, | ||
String profileImage, Item titleItem) | ||
{ | ||
Member member = Member.create(nickname, email, snsAllow, introduction, profileImage, titleItem); | ||
return memberRepository.save(member); | ||
} | ||
|
||
private String getProfileImageFromRequest(List<MultipartFile> images) throws IOException { | ||
String profileImageUrl = null; | ||
if (images != null && !images.get(0).isEmpty()) { | ||
profileImageUrl = uploadProfileImage(images.get(0)); | ||
} | ||
return profileImageUrl; | ||
} | ||
|
||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이부분 protected 접근제어는 왜 제거된건가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
엇 이거 다시 추가해놀을게요!!