Skip to content

Commit

Permalink
Merge pull request #89 from YAPP-Github/fix/ISSUE-88
Browse files Browse the repository at this point in the history
fix: social login & withdraw member
  • Loading branch information
Seokyeong237 authored Feb 13, 2024
2 parents e474bd5 + 2a01b36 commit d59157f
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 143 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,14 @@ public ApiResponse<Object> handleCustomException(CustomException e) {
.message(e.getMessage())
.build();
}

@ExceptionHandler(UnauthorizedException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public ApiResponse<Object> handleUnauthorizedException(UnauthorizedException e) {

return ApiResponse.builder()
.status(401)
.message(e.getMessage())
.build();
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/fullcar/core/response/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ public enum ErrorCode {

/* 400 BAD REQUEST */
FAILED_TO_GENERATE_PUBLIC_KEY(BAD_REQUEST, "애플 공개키 생성 중 문제 발생"),
FAILED_TO_GENERATE_APPLE_TOKEN(BAD_REQUEST, "애플 access Token 생성 중 문제 발생"),
EMAIL_ADDRESS_IN_BLACKLIST(BAD_REQUEST, "블랙리스트에 있는 이메일 주소입니다."),
CANNOT_SEND_TO_OWN_CARPOOL(BAD_REQUEST, "자기자신의 카풀에는 신청할 수 없습니다."),
DUPLICATED_FORM(BAD_REQUEST, "이미 요청을 보낸 카풀입니다."),
Expand All @@ -23,7 +22,6 @@ public enum ErrorCode {
INVALID_FORM_STATE(BAD_REQUEST, "유효하지 않은 신청서 상태입니다."),
EXISTED_CODE_IN_MAIL(BAD_REQUEST, "이미 인증번호를 보냈습니다."),
NOT_MATCHED_CODE(BAD_REQUEST, "인증번호가 일치하지 않습니다."),
INVALID_SOCIAL_TYPE(BAD_REQUEST, "유효하지 않은 소셜 로그인 타입 입니다."),

/* 401 UNAUTHORIZED */
UNAUTHORIZED_KAKAO_TOKEN(UNAUTHORIZED, "유효하지 않은 카카오 토큰"),
Expand All @@ -32,6 +30,8 @@ public enum ErrorCode {
INVALID_CLAIMS(UNAUTHORIZED, "올바르지 않은 Claim"),
SIGNIN_REQUIRED(UNAUTHORIZED, "access, refreshToken 모두 만료되었습니다. 재로그인이 필요합니다."),
INVALID_MEMBER(UNAUTHORIZED, "유효하지 않은 유저"),
INVALID_KAKAO_USER(UNAUTHORIZED, "이미 탈퇴 처리되었거나 유효하지 않은 카카오 유저입니다."),
FAILED_TO_GENERATE_APPLE_REFRESH_TOKEN(UNAUTHORIZED, "애플 refresh Token 생성 중 문제 발생"),

/* 404 NOT FOUND */
NOT_EXIST_USER(NOT_FOUND, "존재하지 않는 사용자입니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fullcar.core.config.jwt.JwtTokenProvider;
import com.fullcar.core.exception.BadRequestException;
import com.fullcar.core.exception.CustomException;
import com.fullcar.core.exception.UnauthorizedException;
import com.fullcar.core.response.ErrorCode;
import com.fullcar.member.application.member.MemberMapper;
Expand All @@ -19,14 +18,12 @@
import lombok.RequiredArgsConstructor;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.bouncycastle.openssl.PEMParser;
Expand Down Expand Up @@ -58,8 +55,8 @@ public class AppleAuthService {
@Value("${apple.client-id}")
private String clientId;

private static final String REQUEST_TOKEN_URL = "https://appleid.apple.com/auth/oauth2/v2/token";
private static final String REVOKE_TOKEN_URL = "https://appleid.apple.com/auth/oauth2/v2/revoke";
private static final String REQUEST_TOKEN_URL = "https://appleid.apple.com/auth/token";
private static final String REVOKE_TOKEN_URL = "https://appleid.apple.com/auth/revoke";

private final ObjectMapper objectMapper;
private final JwtTokenProvider jwtTokenProvider;
Expand Down Expand Up @@ -192,7 +189,7 @@ private String createClientSecret() throws IOException {
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(expirationDate)
.setAudience("https://appleid.apple.com")
.setSubject("com.fullcar.app")
.setSubject(clientId)
.signWith(SignatureAlgorithm.ES256, getPrivateKey())
.compact();
}
Expand All @@ -208,10 +205,7 @@ private PrivateKey getPrivateKey() throws IOException {
}

public AppleAuthTokenResponseDto requestAppleAuthToken(String code) throws IOException {
String secret = createClientSecret();
System.out.println(secret);

RestTemplate restTemplate = new RestTemplateBuilder().build();
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("code", code);
params.add("client_id", clientId);
Expand All @@ -225,18 +219,15 @@ public AppleAuthTokenResponseDto requestAppleAuthToken(String code) throws IOExc

try {
ResponseEntity<AppleAuthTokenResponseDto> response = restTemplate.postForEntity(REQUEST_TOKEN_URL, httpEntity, AppleAuthTokenResponseDto.class);
System.out.println(response.getBody());
return response.getBody();
} catch (Exception e) {
System.out.println(e);
throw new IllegalArgumentException("Apple token error");
//throw new CustomException(ErrorCode.FAILED_TO_GENERATE_APPLE_TOKEN);
throw new UnauthorizedException(ErrorCode.FAILED_TO_GENERATE_APPLE_REFRESH_TOKEN);
}
}

// 회원 탈퇴
public void revoke(Member member) throws IOException {
RestTemplate restTemplate = new RestTemplateBuilder().build();
RestTemplate restTemplate = new RestTemplate();

MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("client_id", clientId);
Expand Down
76 changes: 73 additions & 3 deletions src/main/java/com/fullcar/member/application/auth/AuthService.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,78 @@
package com.fullcar.member.application.auth;


import com.fullcar.core.config.jwt.JwtExceptionType;
import com.fullcar.core.config.jwt.JwtTokenProvider;
import com.fullcar.core.exception.CustomException;
import com.fullcar.core.response.ErrorCode;
import com.fullcar.member.application.car.CarService;
import com.fullcar.member.domain.member.Member;
import com.fullcar.member.domain.member.MemberRepository;
import com.fullcar.member.domain.member.SocialType;
import com.fullcar.member.domain.member.service.MailService;
import com.fullcar.member.presentation.auth.dto.response.AuthResponseDto;
import com.fullcar.member.presentation.auth.dto.response.AuthTokenResponseDto;
import com.fullcar.member.presentation.auth.dto.response.SocialInfoResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

@Component
@RequiredArgsConstructor
public class AuthService {
private final JwtTokenProvider jwtTokenProvider;
private final MemberRepository memberRepository;
private final AppleAuthService appleAuthService;
private final KakaoAuthService kakaoAuthService;
private final CarService carService;
private final MailService mailService;

public AuthResponseDto socialLogin(SocialInfoResponseDto socialResponseDto) {
Member member = memberRepository.findBySocialId(socialResponseDto.getSocialId());
String accessToken = jwtTokenProvider.generateAccessToken(member);

return AuthResponseDto.builder()
.accessToken(accessToken)
.refreshToken(socialResponseDto.getRefreshToken())
.build();
}

public AuthTokenResponseDto getNewToken(String refreshToken) {
// refresh 만료
if (jwtTokenProvider.validateToken(refreshToken) == JwtExceptionType.EXPIRED_JWT_TOKEN) {
throw new CustomException(ErrorCode.SIGNIN_REQUIRED);
}

// 해당 refreshToken을 가진 멤버가 존재하는지 확인
Member member = memberRepository.findByRefreshTokenOrThrow(refreshToken);
String newAccessToken = jwtTokenProvider.generateAccessToken(member);

return AuthTokenResponseDto.builder()
.accessToken(newAccessToken)
.refreshToken(refreshToken)
.build();
}

@Transactional
public void socialLogout(Member member) {
memberRepository.findByIdAndIsDeletedOrThrow(member.getId(), false).clearRefreshTokenAndDeviceToken();
memberRepository.flush();
}

@Transactional
public void withdrawMember(Member member) throws IOException {
if (member.getSocialType() == SocialType.APPLE) {
appleAuthService.revoke(member);
}
else if (member.getSocialType() == SocialType.KAKAO) {
kakaoAuthService.revoke(member);
}

carService.deleteCar(member.getCarId());
mailService.deleteMail(member.getId());
memberRepository.saveAndFlush(member.deleted());

public interface AuthService {
void deleteUser(Member member);
// TODO: 이벤트 기반으로 게시글 및 요청 처리
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fullcar.core.config.jwt.JwtTokenProvider;
import com.fullcar.core.exception.NotFoundException;
import com.fullcar.core.exception.UnauthorizedException;
import com.fullcar.core.response.ErrorCode;
import com.fullcar.member.application.member.MemberMapper;
import com.fullcar.member.domain.auth.SocialId;
Expand All @@ -16,7 +17,6 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -94,8 +94,7 @@ private void createMember(SocialId socialId, String deviceToken, String refreshT

// 회원 탈퇴
public void revoke(Member member) {
RestTemplate restTemplate = new RestTemplateBuilder().build();

RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "KakaoAK " + adminKey);
Expand All @@ -106,10 +105,14 @@ public void revoke(Member member) {

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

restTemplate.exchange(
KAKAO_UNLINK_ENDPOINT,
HttpMethod.POST,
request,
String.class);
try {
restTemplate.exchange(
KAKAO_UNLINK_ENDPOINT,
HttpMethod.POST,
request,
String.class);
} catch (HttpClientErrorException e) {
throw new UnauthorizedException(ErrorCode.INVALID_KAKAO_USER);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fullcar.member.domain.auth.SocialId;
import com.fullcar.member.domain.member.Company;
import com.fullcar.member.domain.member.SocialType;
import com.fullcar.member.domain.member.service.MemberIdService;
import com.fullcar.member.domain.member.Member;
import com.fullcar.member.presentation.member.dto.request.OnBoardingRequestDto;
Expand Down Expand Up @@ -59,6 +60,7 @@ public Member toKakaoLoginEntity(SocialId socialId, String deviceToken, String r
.socialId(socialId)
.deviceToken(deviceToken)
.refreshToken(refreshToken)
.socialType(SocialType.KAKAO)
.build();
}

Expand All @@ -69,6 +71,7 @@ public Member toAppleLoginEntity(SocialId socialId, String appleRefreshToken, St
.appleRefreshToken(appleRefreshToken)
.deviceToken(deviceToken)
.refreshToken(refreshToken)
.socialType(SocialType.APPLE)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
@Repository
public interface MailRepository extends JpaRepository<Mail, MailId> {
Mail findByMemberId(MemberId memberId);
boolean existsByMemberId(MemberId memberId);
}
3 changes: 3 additions & 0 deletions src/main/java/com/fullcar/member/domain/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public class Member {

private SocialId socialId;

@Enumerated(EnumType.STRING)
private SocialType socialType;

@Embedded
private Company company;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public enum MemberSocialType {
public enum SocialType {
KAKAO,
APPLE
}
6 changes: 4 additions & 2 deletions src/main/java/com/fullcar/member/infra/MailClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ public void checkMailAuthenticationCode(Member member, CodeRequestDto codeReques
@Transactional
@Override
public void deleteMail(MemberId memberId) {
Mail mail = mailRepository.findByMemberId(memberId);
mailRepository.delete(mail);
if (mailRepository.existsByMemberId(memberId)) {
Mail mail = mailRepository.findByMemberId(memberId);
mailRepository.delete(mail);
}
}
}
Loading

0 comments on commit d59157f

Please sign in to comment.