메인 프로젝트를 하면서 REST API로 카카오 로그인을 구현해보았다.
해당 부분을 기억하기 위해 이 글을 작성하였다.
이 포스팅은 프로젝트 과정에서 흐름을 기억하기 위해 작성한 것으로, 기본 흐름의 틀정도라고 생각하면 좋을 듯 하다.
해당 포스팅의 코드는 아래의 깃헙 주소에서도 확인 가능.
❗️본 포스팅은 이전 포스팅에서 이어집니다❗️
✨ 들어가기 전에 왜 권한 수정이 로그인에 같이 포스팅 하는지✨
: 메인 프로젝트 서버는 생산자와 소비자가 나뉘어져 있었다. 그렇기 때문에 무조건 둘 중의 하나의 역할을 선택하고 해당 권한이 있어야 했다. 하지만 소셜 로그인 사용자는 선택하기 어렵기 때문에, 따로 선택할 수 있는 페이지를 만들었다. 중요한 것은 이 페이지는 "소셜"권한 사용자만 접근이 가능하다는 것이다. 만약 생산자나 소비자로 역할을 선택했다면 그 이후에는 접근이 불가하다.
왜냐하면, 한 번 정해진 역할(권한)은 수정할 수 없기 때문이다.
1️⃣ PatchDto 클래스 생성
- 요청이 들어올 DTO 클래스를 생성
@Getter
public class SocialPatchDto {
private String role;
}
2️⃣ MemberService에 소셜 권한 관련 함수 추가
- MemberService 클래스에 소셜 권한을 위한 함수를 추가
@Service
@Slf4j
@Transactional
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
private final PasswordEncoder passwordEncoder;
private final CustomAuthorityUtils authorityUtils;
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final JwtProvider jwtProvider;
private final RedisTemplate<String, Object> redisTemplate;
...
/* 소셜 로그인 권한 수정 */
public Member updateSocial(String role, long memberId) {
Member member = findVerifiedMember(memberId);
checkSocialRole(member.getRole());
if (role.equalsIgnoreCase("CLIENT")) {
member.setCreateMember(
"소셜 로그인 사용자, 권한 수정 완료",
"CLIENT",
List.of("CLIENT"),
ProviderType.KAKAO
);
member.setClient(new Client());
} else if (role.equalsIgnoreCase("SELLER")) {
member.setCreateMember(
"소셜 로그인 사용자, 권한 수정 완료",
"SELLER",
List.of("SELLER"),
ProviderType.KAKAO
);
member.setSeller(new Seller());
} else {
throw new RuntimeException("수정할 수 없습니다.");
}
return member;
}
...
/* 존재하는 회원인지 확인 */
private Member findVerifiedMember(long memberId) {
Optional<Member> optionalMember = memberRepository.findById(memberId);
Member findMember = optionalMember.orElseThrow(
() -> new RuntimeException("회원을 찾을 수 없습니다."));
return findMember;
}
/* social 역할 확인 */
private void checkSocialRole(String role) {
if (!role.equalsIgnoreCase("SOCIAL")) {
throw new RuntimeException("소셜 권한 사용자가 아닙니다.");
}
}
}
3️⃣ MemberController에 소셜 권한 관련 함수 추가
- MemberController 클래스에 소셜 권한을 위한 함수를 추가
- 토큰을 재발급 받는 이유 : 토큰에는 역할이 담겨있기 때문
@Slf4j
@RestController
@RequiredArgsConstructor
@Transactional
public class MemberController {
private final MemberService memberService;
private final MemberMapper mapper;
private final KakaoService kakaoService;
/* 소셜 로그인 유저 권한 수정 */
@PatchMapping("/social/{member_id}")
public ResponseEntity patchSocial(@PathVariable("member_id") @Positive long memberId,
@RequestBody SocialPatchDto requestBody) {
Member member = memberService.updateSocial(requestBody.getRole(), memberId);
LoginRequestDto request = new LoginRequestDto(member.getEmail(), member.getPassword());
/* 여기서 토큰 재발급 */
TokenDto tokenDto = memberService.kakaoLogin(request);
HttpHeaders httpHeaders = setHeader(tokenDto.getAccessToken());
/* 역할에 따라 응답 바디가 다르므로, 나누어 주었다.*/
if(member.getRole().equals("SELLER")) {
return new ResponseEntity<>(mapper.memberToSellerResponseDto(member), httpHeaders, HttpStatus.OK);
} else if (member.getRole().equals("CLIENT")) {
return new ResponseEntity<>(mapper.memberToClientResponseDto(member), httpHeaders, HttpStatus.OK);
}
/* 로그인이 실패할 경우, 문제가 존재하는 것 */
throw new RuntimeException("로그인에 실패하였습니다.");
}
/* 로그인 헤더 설정 */
private HttpHeaders setHeader(String token) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Authorization", token);
return httpHeaders;
}
}
'Spring' 카테고리의 다른 글
[Spring] REST Docs (0) | 2023.01.04 |
---|---|
[Spring] 로그인 구현 3 - 카카오 로그인 구현 (1) | 2022.12.20 |
[Spring] 로그인 구현 2 - 회원 가입 & 자체 로그인 구현 (1) | 2022.12.20 |
[Spring] 로그인 구현 1 - 회원 엔티티, Mapper, Repository 구현 (0) | 2022.12.20 |
[Spring] Transaction (0) | 2022.12.19 |
댓글