Skip to content
72 changes: 72 additions & 0 deletions src/main/java/com/favoriteplace/app/member/Facade/AuthFacade.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.favoriteplace.app.member.Facade;

import com.favoriteplace.app.member.controller.dto.KaKaoSignUpRequestDto;
import com.favoriteplace.app.member.controller.dto.MemberDto;
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.member.service.MemberService;
import com.favoriteplace.app.member.service.TokenService;
import com.favoriteplace.global.auth.kakao.KakaoClient;
import com.favoriteplace.global.auth.provider.JwtTokenProvider;

import lombok.RequiredArgsConstructor;

import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

@Component
@RequiredArgsConstructor
public class AuthFacade {
private final MemberService memberService;
private final TokenService tokenService;
private final JwtTokenProvider jwtTokenProvider;
private final KakaoClient kakaoClient;

public TokenInfoDto kakaoLogin(final String token) {
String email = kakaoClient.getUserInfo(token).kakaoAccount().email();
memberService.kakaoLogin(email);
return getTokenDto(email);
}

public MemberDto.MemberSignUpResDto kakaoSignUp(
final String token,
final KaKaoSignUpRequestDto memberSignUpReqDto,
final List<MultipartFile> images
) throws IOException {
String email = kakaoClient.getUserInfo(token).kakaoAccount().email();
TokenInfoDto tokenDto = getTokenDto(email);
Member member = memberService.kakaoSignUp(email, memberSignUpReqDto, images);
tokenService.updateRefreshToken(member, tokenDto.refreshToken());
return MemberDto.MemberSignUpResDto.from(member, tokenDto);
Comment thread
JungYoonShin marked this conversation as resolved.
}

public MemberDto.MemberSignUpResDto signup(
final MemberSignUpReqDto memberSignUpReqDto,
final List<MultipartFile> images
) throws IOException {
Member member = memberService.signup(memberSignUpReqDto, images);
TokenInfoDto tokenDto = getTokenDto(member.getEmail());
tokenService.updateRefreshToken(member, tokenDto.refreshToken());
return MemberDto.MemberSignUpResDto.from(member, tokenDto);
}

public void logout(String accessToken) {
Authentication authentication = jwtTokenProvider.getAuthentication(accessToken);
String email = authentication.getName();
Long expiration = jwtTokenProvider.getExpiration(accessToken);
Member member = memberService.findMember(email);
tokenService.logoutAndInvalidateToken(member, expiration, accessToken);
}

private TokenInfoDto getTokenDto(String email) {
return TokenInfoDto.of(
jwtTokenProvider.issueAccessToken(email),
jwtTokenProvider.issueRefreshToken(email)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.favoriteplace.app.member.controller;

import com.favoriteplace.app.member.Facade.AuthFacade;
import com.favoriteplace.app.member.controller.dto.TokenInfoDto;
import com.favoriteplace.global.auth.provider.JwtTokenProvider;
import com.favoriteplace.app.member.controller.dto.KaKaoSignUpRequestDto;
Expand Down Expand Up @@ -34,16 +35,17 @@
@RequiredArgsConstructor
@RequestMapping("/auth")
public class MemberController {
private final MemberService memberService;
private final AuthFacade authFacade;
private final MailSendService mailSendService;
private final MemberService memberService;
private final JwtTokenProvider jwtTokenProvider;
private final SecurityUtil securityUtil;

@PostMapping("/login/kakao")
public ResponseEntity<TokenInfoDto> kakaoLogin(
@RequestHeader("Authorization") final String token
) {
return ResponseEntity.ok(memberService.kakaoLogin(token));
return ResponseEntity.ok(authFacade.kakaoLogin(token));
}

@PostMapping("/signup/kakao")
Expand All @@ -52,15 +54,15 @@ public ResponseEntity<MemberDto.MemberSignUpResDto> kakaoSignUp(
@RequestPart(required = false) final List<MultipartFile> images,
@RequestPart final KaKaoSignUpRequestDto data
) throws IOException {
return ResponseEntity.ok(memberService.kakaoSignUp(token, data, images));
return ResponseEntity.ok(authFacade.kakaoSignUp(token, data, images));
}

@PostMapping("/signup")
public ResponseEntity<MemberDto.MemberSignUpResDto> signup(
@RequestPart(required = false) List<MultipartFile> images,
@RequestPart MemberSignUpReqDto data
) throws IOException {
return ResponseEntity.ok(memberService.signup(data, images));
return ResponseEntity.ok(authFacade.signup(data, images));
}

@PostMapping("/signup/email")
Expand Down Expand Up @@ -97,8 +99,7 @@ public ResponseEntity<String> setNewPassword(
@PostMapping("/logout")
public ResponseEntity<String> logout(HttpServletRequest request) {
String accessToken = securityUtil.resolveToken(request);
memberService.logout(accessToken);

authFacade.logout(accessToken);
return ResponseEntity.ok("로그아웃 되었습니다.");
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/favoriteplace/app/member/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public class Member extends BaseTimeEntity {
public static Member create(
String nickname, String email,
boolean snsAllow, String introduction,
String profileImage, Item titleItem)
String profileImage, Item titleItem, LoginType loginType)
{
return Member.builder()
.nickname(nickname)
Expand All @@ -88,7 +88,7 @@ public static Member create(
.description(introduction)
.profileImageUrl(profileImage)
.point(0L)
.loginType(LoginType.KAKAO)
.loginType(loginType)
.profileTitle(titleItem)
.status(MemberStatus.Y)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ public class MailSendService {

private final RedisUtil redisUtil;


//임의의 6자리 양수를 반환합니다.
public void makeRandomNumber() {
Random r = new Random();
String randomNumber = "";
Expand All @@ -43,23 +41,21 @@ public void makeRandomNumber() {
authNumber = Integer.parseInt(randomNumber);
}

//mail을 어디서 보내는지, 어디로 보내는지 , 인증 번호를 html 형식으로 어떻게 보내는지 작성합니다.
public MemberDto.EmailSendResDto joinEmail(String email) {
makeRandomNumber();
String setFrom = host; // email-config에 설정한 자신의 이메일 주소를 입력
String toMail = email;
String title = "[최애의 장소] 회원 가입 인증 이메일 입니다."; // 이메일 제목
String title = "[최애의 장소] 회원 가입 인증 이메일 입니다.";
String content =
"최애의 장소를 방문해주셔서 감사합니다." + //html 형식으로 작성 !
"최애의 장소를 방문해주셔서 감사합니다." +
"<br><br>" +
"인증 번호는 " + authNumber + "입니다." +
"<br>" +
"인증번호를 올바르게 입력해주세요 :)"; //이메일 내용 삽입
"인증번호를 올바르게 입력해주세요 :)";
mailSend(setFrom, toMail, title, content);
return new MemberDto.EmailSendResDto(authNumber);
}

//이메일을 전송합니다.
public void mailSend(String setFrom, String toMail, String title, String content) {
//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성
MimeMessage message = mailSender.createMimeMessage();
Expand Down
107 changes: 30 additions & 77 deletions src/main/java/com/favoriteplace/app/member/service/MemberService.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.favoriteplace.app.member.service;

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.member.controller.dto.UserInfoResponseDto;
Expand All @@ -14,6 +12,7 @@
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.domain.enums.LoginType;
import com.favoriteplace.app.member.repository.MemberRepository;
import com.favoriteplace.global.auth.kakao.KakaoClient;
import com.favoriteplace.global.auth.provider.JwtTokenProvider;
Expand All @@ -22,12 +21,11 @@

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;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -36,74 +34,55 @@
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
@Slf4j
public class MemberService {

private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
private final JwtTokenProvider jwtTokenProvider;
private final AmazonS3ImageManager amazonS3ImageManager;
private final ItemRepository itemRepository;
private final RedisTemplate redisTemplate;
private final KakaoClient kakaoClient;

public TokenInfoDto kakaoLogin(final String token) {
String userEmail = getUserEmailFromKakao(token);

// 최초 로그인이라면 회원가입 API로 통신하도록
Member member = findMember(userEmail);

return issueToken(userEmail);
public void kakaoLogin(final String email) {
Member member = findMember(email);
}

@Transactional
public MemberDto.MemberSignUpResDto kakaoSignUp(
final String token,
public Member kakaoSignUp(
final String email,
final KaKaoSignUpRequestDto memberSignUpReqDto,
final List<MultipartFile> images
) throws IOException {

String userEmail = getUserEmailFromKakao(token);

memberRepository.findByEmail(userEmail)
memberRepository.findByEmail(email)
.ifPresent(a -> {
throw new RestApiException(USER_ALREADY_EXISTS);
});

String profileImage = getProfileImageFromRequest(images);

Item titleItem = getDefaultProfileItem();

Member member = saveUser(memberSignUpReqDto.nickname(), userEmail,
memberSignUpReqDto.snsAllow(), memberSignUpReqDto.introduction(),
profileImage, titleItem);

TokenInfoDto tokenInfo = issueToken(userEmail);
member.updateRefreshToken(tokenInfo.refreshToken());

return MemberDto.MemberSignUpResDto.from(member, tokenInfo);

Member member = saveUser(
memberSignUpReqDto.nickname(),
email,
memberSignUpReqDto.snsAllow(),
memberSignUpReqDto.introduction(),
profileImage,
titleItem,
LoginType.KAKAO
);
return member;
}

@Transactional
public MemberDto.MemberSignUpResDto signup(
public Member signup(
final MemberSignUpReqDto memberSignUpReqDto,
final List<MultipartFile> images
) throws IOException {

String password = passwordEncoder.encode(memberSignUpReqDto.password());

Item titleItem = getDefaultProfileItem();

String profileImage = getProfileImageFromRequest(images);

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);
profileImage, titleItem, LoginType.SELF);
member.updatePassword(password);
return member;
}

public String uploadProfileImage(MultipartFile profileImage) throws IOException {
Expand All @@ -113,14 +92,12 @@ public String uploadProfileImage(MultipartFile profileImage) throws IOException
public MemberDto.EmailDuplicateResDto emailDuplicateCheck(EmailSendReqDto emailSendReqDto) {
String email = emailSendReqDto.getEmail();
Boolean isExists = memberRepository.findByEmail(email).isPresent();

return new EmailDuplicateResDto(isExists);
}

@Transactional
public void setNewPassword(String email, String password) {
Member member = findMember(email);

String newPassword = passwordEncoder.encode(password);
member.updatePassword(newPassword);
}
Expand All @@ -132,49 +109,25 @@ public UserInfoResponseDto getUserInfo(Member member) {
return null;
}

@Transactional
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(accessToken);
redisTemplate.opsForValue()
.set(accessToken, "logout", expriation, TimeUnit.MICROSECONDS);
}

private Member findMember(final String email) {
public 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);
String profileImage, Item titleItem, LoginType loginType) {
Member member =
Member.create(
nickname, email,
snsAllow, introduction,
profileImage, titleItem, loginType
);
return memberRepository.save(member);
}

Expand Down
Loading
Loading