Skip to content

Commit

Permalink
Merge pull request #187 from gunsight1/feature_member_for_kakao
Browse files Browse the repository at this point in the history
feature :: 카카오 로그인
  • Loading branch information
gunsight1 authored Feb 26, 2024
2 parents 620efb3 + 8248b76 commit c894b6e
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ public enum MemberBusinessCode implements BusinessCode {
SUCCESS_VALIDATE_PASSWORD_MEMBER(HttpStatus.OK.value(), "BMC008", "비밀번호가 확인 되었습니다."),
SUCCESS_REQUEST_UPDATE_WASH_INFO_MEMBER(HttpStatus.OK.value(), "BMC009", "WashInfo 정보가 변경 되었습니다."),
SUCCESS_REQUEST_UPDATE_CAR_INFO_MEMBER(HttpStatus.OK.value(), "BMC010", "CarInfo 정보가 변경 되었습니다."),
SUCCESS_REQUEST_FIND_MEMBER_ID(HttpStatus.OK.value(), "BMC011", "회원 아이디 찾기 메일이 발송되었습니다."),
SUCCESS_REQUEST_FIND_MEMBER_ID(HttpStatus.OK.value(), "BMC011","회원 아이디 찾기 메일이 발송되었습니다."),
SUCCESS_REQUEST_SEND_RESET_PASSWORD_EMAIL(HttpStatus.OK.value(), "BMC012", "회원 비밀번호 초기화 메일이 발송되었습니다."),
SUCCESS_REQUEST_RESET_PASSWORD_PAGE(HttpStatus.FOUND.value(), "BMC013", "비밀번호 초기화 토큰이 유효하므로 비밀번호 초기화 페이지로 접근합니다."),
SUCCESS_REQUEST_RESET_PASSWORD(HttpStatus.OK.value(), "BMC013", "비밀번호가 초기화되었습니다.");
SUCCESS_REQUEST_RESET_PASSWORD(HttpStatus.OK.value(), "BMC014", "비밀번호가 초기화되었습니다."),
SUCCESS_REQUEST_LOGIN_MEMBER_KAKAO(HttpStatus.OK.value(), "BMC015", "로그인 성공");

private final int status;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public enum MemberErrorCode implements ErrorCode {
FAILED_GENERATE_LOGIN_REQUEST_INFO(HttpStatus.INTERNAL_SERVER_ERROR.value(), "EMC005", "정보 불일치로 인한 로그인 정보 생성 실패"),
FAILED_REQUEST_LOGIN(HttpStatus.BAD_REQUEST.value(), "EMC006", "정보 불일치로 인한 로그인 실패"),
FAILED_FIND_MEMBER_INFO(HttpStatus.BAD_REQUEST.value(), "EMC007", "요청 회원정보가 존재하지 않습니다."),
EXPIRED_PASSWORD_RESET_TOKEN(HttpStatus.NOT_FOUND.value(), "EMC008", "유효하지 않은 비밀번호 초기화 토큰입니다");

EXPIRED_PASSWORD_RESET_TOKEN(HttpStatus.NOT_FOUND.value(), "EMC008", "유효하지 않은 비밀번호 초기화 토큰입니다"),
FAILED_REQUEST_LOGIN_FOR_KAKAO(HttpStatus.BAD_REQUEST.value(), "EMC009", "카카오 로그인 정보를 찾을 수 없습니다.");

private final int status;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kernel360.member.controller;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.kernel360.carinfo.entity.CarInfo;
import com.kernel360.member.code.MemberBusinessCode;
import com.kernel360.member.dto.CarInfoDto;
Expand Down Expand Up @@ -108,4 +109,12 @@ public ResponseEntity<ApiResponse<Object>> resetPassword(@RequestBody MemberCred

return ApiResponse.toResponseEntity(MemberBusinessCode.SUCCESS_REQUEST_RESET_PASSWORD);
}

@GetMapping("/login/forKakao")
public ResponseEntity<ApiResponse<MemberDto>> loginForKakao(@RequestHeader("Authorization") String accessToken) {

MemberDto member = memberService.loginForKakao(accessToken);

return ApiResponse.toResponseEntity(SUCCESS_REQUEST_LOGIN_MEMBER, member);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.kernel360.member.dto;

public record KakaoUserDto(
String id,
String email
) {
public static KakaoUserDto of(
String id,
String email
){
return new KakaoUserDto(
id,
email
);
}
}
16 changes: 16 additions & 0 deletions module-api/src/main/java/com/kernel360/member/dto/MemberDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ public static MemberDto from(Member entity) {
);
}

public static MemberDto fromKakao(MemberDto dto, String token) {
return MemberDto.of(
dto.memberNo(),
dto.id(),
dto.email(),
dto.password(),
dto.gender(),
dto.age(),
dto.createdAt(),
dto.createdBy(),
dto.modifiedAt(),
dto.modifiedBy(),
token
);
}

public Member toEntity() {
return Member.of(
this.memberNo(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public enum Age {
AGE_30(30),
AGE_40(40),
AGE_50(50),
AGE_60(60);
AGE_60(60),
AGE_99(99);

private final int value;

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

@RequiredArgsConstructor
public enum Gender {
man(0),
woman(1);
MALE(0),
FEMALE(1),
OTHERS(99);

private final int value;
public static String ordinalToName(int value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.kernel360.member.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kernel360.exception.BusinessException;
import com.kernel360.member.code.MemberErrorCode;
import com.kernel360.member.dto.KakaoUserDto;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@Component
public class KakaoRequest {

public KakaoUserDto getKakaoUserByToken(String accessToken) {

String url = "https://kapi.kakao.com/v2/user/me";

HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Bearer "+accessToken);
headers.set("charset", "utf-8");

HttpEntity<String> requestEntity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);

ObjectMapper mapper = new ObjectMapper();
Map<String, Object> kakaoResponse;

try {
kakaoResponse = mapper.readValue(responseEntity.getBody(), HashMap.class);
}catch (Exception e){
throw new BusinessException(MemberErrorCode.FAILED_REQUEST_LOGIN_FOR_KAKAO);
}
Map<String, Object> kakaoAccount = mapper.convertValue(kakaoResponse.get("kakao_account"), HashMap.class);

KakaoUserDto dto = KakaoUserDto.of(kakaoResponse.get("id").toString(),kakaoAccount.get("email").toString());

return dto;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
import com.kernel360.commoncode.service.CommonCodeService;
import com.kernel360.exception.BusinessException;
import com.kernel360.member.code.MemberErrorCode;
import com.kernel360.member.dto.CarInfoDto;
import com.kernel360.member.dto.MemberDto;
import com.kernel360.member.dto.MemberInfo;
import com.kernel360.member.dto.WashInfoDto;
import com.kernel360.member.dto.*;
import com.kernel360.member.entity.Member;
import com.kernel360.member.enumset.Age;
import com.kernel360.member.enumset.Gender;
Expand Down Expand Up @@ -39,6 +36,7 @@ public class MemberService {
private final CommonCodeService commonCodeService;
private final CarInfoRepository carInfoRepository;
private final WashInfoRepository washInfoRepository;
private final KakaoRequest kakaoRequest;

@Transactional
public void joinMember(MemberDto requestDto) {
Expand Down Expand Up @@ -191,6 +189,7 @@ public MemberDto findByMemberId(String memberId) {

return MemberDto.from(member);
}

@Transactional
public void resetPasswordByMemberId(String memberId, String newPassword) {
Member member = memberRepository.findOneById(memberId);
Expand All @@ -201,4 +200,20 @@ public void resetPasswordByMemberId(String memberId, String newPassword) {
member.updatePassword(ConvertSHA256.convertToSHA256(newPassword));
}

@Transactional
public MemberDto loginForKakao(String accessToken) {

KakaoUserDto kakaoUser = kakaoRequest.getKakaoUserByToken(accessToken);
if(Objects.isNull(memberRepository.findOneById(kakaoUser.id()))){
memberRepository.save(Member.createForKakao(kakaoUser.id(), kakaoUser.email(), "kakao", Gender.OTHERS.ordinal(), Age.AGE_99.ordinal()));
}

MemberDto memberDto = MemberDto.from(memberRepository.findOneById(kakaoUser.id()));

String loginToken = jwt.generateToken(memberDto.id());

authService.saveAuthByMember(memberDto.memberNo(), ConvertSHA256.convertToSHA256(loginToken));

return MemberDto.fromKakao(memberDto, loginToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.restdocs.payload.JsonFieldType;

import static com.kernel360.common.utils.RestDocumentUtils.getDocumentRequest;
import static com.kernel360.common.utils.RestDocumentUtils.getDocumentResponse;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.*;
Expand Down Expand Up @@ -36,6 +38,8 @@ class AuthControllerTest extends ControllerTest {
.andExpect(jsonPath("$.code").value("BAC001"))
.andExpect(jsonPath("$.message").value("JWT 토큰 재발급 성공"))
.andDo(document("auth/reissuanceJWT",
getDocumentRequest(),
getDocumentResponse(),
responseFields(
fieldWithPath("status").description("상태 코드"),
fieldWithPath("message").description("응답 메시지"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class MemberControllerTest extends ControllerTest {
void 회원입요청() throws Exception {

/** given 목데이터 세팅 **/
MemberDto memberDto = MemberDto.of("testID", "[email protected]", "testPassword", "man", "30");
MemberDto memberDto = MemberDto.of("testID", "[email protected]", "testPassword", "MALE", "30");

ObjectMapper objectMapper = new ObjectMapper();
String param = objectMapper.writeValueAsString(memberDto);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public class Member extends BaseEntity {
@Column(name = "age")
private int age;


public static Member of(Long memberNo, String id, String email, String password, int gender, int age) {

return new Member(memberNo, id, email, password, gender, age);
Expand Down Expand Up @@ -125,4 +124,10 @@ public void updateCarInfo(CarInfo carInfo) {
this.carInfo = carInfo;
}

public static Member createForKakao(String id, String email, String password, int gender, int age) {

return new Member(id, email, password, gender, age);
}


}

0 comments on commit c894b6e

Please sign in to comment.