쌓고 쌓다

[스프링 부트] 카카오 로그인 회원 저장 방법- 31 본문

프로그래밍/spring

[스프링 부트] 카카오 로그인 회원 저장 방법- 31

승민아 2023. 9. 17. 17:33

다양한 소셜 플랫폼을 통해 로그인하는 회원을 어떻게 저장하면 좋을까?

 

소셜 로그인 방법이 카카오, 네이버, 구글 등으로 다양하고

서비스 자체 회원가입 방법이 존재할 수 있다.

 

이 상황을 고려하여 DB를 간단히 설계해봤다.

 

Member 테이블

CREATE TABLE MEMBER (
    id bigint AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    sns_identifier VARCHAR(255),
    member_type VARCHAR(255) NOT NULL,
    PRIMARY KEY (id)
);
  • sns_identifier : 소셜 로그인 플랫홈에서 제공하는 고유한 키를 저장
  • member_type : 일반 회원, 카카오, 네이버, 구글 등으로 값을 가짐

소셜 로그인을 통해 로그인시

기존 회원인지 새 회원인지 판별은

memberType과 snsIdentifier을 통해 해주면 좋겠다.

회원 서비스 타입마다 고유한 키를 제공해주니 말이다.

 

자체 회원가입은 추후에 학습후 리팩토링을 거쳐볼 계획이다.

 

MemberType

import lombok.Getter;

@Getter
public enum MemberType {

    NORMAL("일반 회원"),
    KAKAO("카카오 회원");
    private final String description;

    MemberType(String description) {
        this.description = description;
    }

}

ENUM에 description 사용에 관한 내용을 추후에 정리해보면 좋을 것 같다.

 

 

카카오 로그인 API 사용 방법에 대해서는 다뤘기에

간단히 로그인 회원 저장에 대해서만 설명한다.

 

KakaoController

@Controller
@RequiredArgsConstructor
public class KakaoController {

    private final String tokenUri = "https://kauth.kakao.com/oauth/token";
    private final String userInfoUri = "https://kapi.kakao.com/v2/user/me";

    private final MemberService memberService;

    @Value("${client_id}")
    private String client_id;

    @Value("${secret_id}")
    private String secret_id; // 보안 추가

    @GetMapping("/kakaoOauth")
    public String getToken(@RequestParam("code") String code) {

        // Token 발급
        ...
        String token = (String) restTemplate.exchange(tokenUri, HttpMethod.POST, httpEntity, Map.class).getBody().get("access_token");

        // 회원 정보 호출
        Member memberInfo = getInfo(token);
        Member saveMember = memberService.save(memberInfo);

        return "redirect:/";
    }

    public Member getInfo(String token) {
    	//토큰으로 회원 정보 가져오기
        ...
        String response = restTemplate.exchange(userInfoUri, HttpMethod.GET, httpEntity, String.class).getBody();

        Member member = new Member();
        member.setSnsIdentifier(snsIdentifier);
        member.setName(name);
        member.setEmail(email);
        member.setMemberType(memberType);
        return member;
    }

}

토큰을 통해 getInfo()로 카카오 사용자 정보를 통해 Member 객체를 생성한다.

이때 생성된 Member 객체를 가지고 memberService의 저장 로직인 save 메서드를 호출했다.

 

MemberService

@Service
@RequiredArgsConstructor
public class MemberService {

    private final MemberRepository memberRepository;

    public Member save(Member member) {
        if(member.getMemberType()== MemberType.NORMAL) { // 시큐리티 배우고 해보자.

        } else if (member.getMemberType() == MemberType.KAKAO) {
            Optional<Member> findMember = memberRepository.findByMemberTypeAndSnsIdentifier(MemberType.KAKAO, member.getSnsIdentifier());
            if(findMember.isPresent()) { // 기존 카카오 회원
                return findMember.get();
            }
        }

        return memberRepository.save(member); // 새 회원
    }
}

회원 서비스는 회원 저장 로직을 담당한다.

파라미터로 받은 Member 객체의 가입 타입이 KAKAO라면

MemberType과 플랫폼에서 제공하는 SnsIdentifie(고유 식별자)로 DB에서 조회를 한다.

 

가입 타입과 식별자를 사용하는 이유는 다음과 같다.

이메일로 회원을 찾는다면

누군가 플랫폼 탈퇴 . 다른 누군가가 똑같은 플랫폼으로 똑같은 이메일로 가입하면 기존 회원으로 인식할 수 있다.

식별자로만 회원을 찾는다면

snsIdentifier로만 하면 다른 플래폼의 소셜 로그인 식별자와 겹칠 수도 있음.

그래서 플랫폼 타입과 그 플랫폼에서 제공하는 키를 같이 사용했다.

 

일반 회원은 추후에 작업한다.

 

MemberRepository

public interface MemberRepository extends JpaRepository<Member, Long> {
    Optional<Member> findByMemberTypeAndSnsIdentifier(MemberType memberType, Long snsIdentifier);
}

 

 

카카오 로그인 DB 저장 결과

 

다음으로는 세션과 인터셉터로 인증 체크를 추가해보고

게시글, 댓글 작성시 회원 정보를 통해 DB에 저장하게 해보자.

Comments