쌓고 쌓다
[스프링 부트] 카카오 로그인 회원 저장 방법- 31 본문
다양한 소셜 플랫폼을 통해 로그인하는 회원을 어떻게 저장하면 좋을까?
소셜 로그인 방법이 카카오, 네이버, 구글 등으로 다양하고
서비스 자체 회원가입 방법이 존재할 수 있다.
이 상황을 고려하여 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에 저장하게 해보자.
'프로그래밍 > spring' 카테고리의 다른 글
HTML에서 날짜 입력 받아 서버에서 LocalDate로 받기 (0) | 2023.09.20 |
---|---|
[스프링 부트] 모든 요청 로그 남기기(인터셉터) (0) | 2023.09.19 |
스프링 부트에서 JS 파일 경로 (404 에러) (0) | 2023.09.17 |
application.properties 값을 필드에 사용하는 법 (0) | 2023.09.16 |
[스프링 부트] Form 전송 객체 분리(검증 달리하기) - 30 (0) | 2023.09.14 |