ζ Spring 카카오 로그인 DB 저장

@Autowired·2022년 1월 3일
3

Spring Framework

목록 보기
6/6

Spring 카카오 로그인 DB저장하기!

Spring 에서 카카오 로그인 정보를 DB에 저장하는 방법을 정리해볼려고 합니다.
이전 카카오 로그인 REST API에서 추가로 몇가지만 작성하면 되므로 참고해주세요.

  • 참고사항 (필독!)
    • DB : MySQL
    • 사용 tool : Spring Framework
    • ☭ Spring 카카오 로그인 REST API 보러가기
    • 제가 프로젝트를 진행하며 정리하는 내용이므로 완벽하지 않습니다, 참고용으로만 봐주세요!

DB에 table 생성

create table kakao_table (
	k_number bigint auto_increment,
    k_name varchar(20) not null,
    k_email varchar(50) not null,
    constraint primary key(k_number)
);

카카오 & 네이버에서 제공하는 정보는 String 타입이므로 varchar로 지정합니다.


KakaoDTO 생성

  • 우선 카카오 서버에서 받은 정보를 저장할 kakaoDTO를 하나 생성해줍니다.
    우선 pk로 쓸 넘버값이 필요하고, 이름(카톡 닉네임)과 이메일만 받기때문에 아래와 같이 작성해줍니다.
package com.spring.project.dto;

import lombok.Data;

@Data
public class KakaoDTO {

	private long k_number;
	private String k_name;
	private String k_email;
	
}

Service getUserInfo 메서드에 내용 추가

  • 이전 Service에 만든 getUserInfo 메서드에 DB에 담을 준비를 해봅시다.

// 클래스 주입.
@Autowired
private MemberRepository mr;

// 메서드 리턴타입 KakaoDTO로 변경 및 import.
public KakaoDTO getUserInfo(String access_Token) {
		HashMap<String, Object> userInfo = new HashMap<String, Object>();
		String reqURL = "https://kapi.kakao.com/v2/user/me";
		try {
			URL url = new URL(reqURL);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Authorization", "Bearer " + access_Token);
			int responseCode = conn.getResponseCode();
			System.out.println("responseCode : " + responseCode);
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = "";
			String result = "";
			while ((line = br.readLine()) != null) {
				result += line;
			}
			System.out.println("response body : " + result);
			JsonParser parser = new JsonParser();
			JsonElement element = parser.parse(result);
			JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
			JsonObject kakao_account = element.getAsJsonObject().get("kakao_account").getAsJsonObject();
			String nickname = properties.getAsJsonObject().get("nickname").getAsString();
			String email = kakao_account.getAsJsonObject().get("email").getAsString();
			userInfo.put("nickname", nickname);
			userInfo.put("email", email);
		} catch (IOException e) {
			e.printStackTrace();
		}

		// catch 아래 코드 추가.
		KakaoDTO result = mr.findkakao(userInfo);
		// 위 코드는 먼저 정보가 저장되있는지 확인하는 코드.
		System.out.println("S:" + result);
		if(result==null) {
		// result가 null이면 정보가 저장이 안되있는거므로 정보를 저장.
			mr.kakaoinsert(userInfo);
			// 위 코드가 정보를 저장하기 위해 Repository로 보내는 코드임.
			return mr.findkakao(userInfo);
			// 위 코드는 정보 저장 후 컨트롤러에 정보를 보내는 코드임.
			//  result를 리턴으로 보내면 null이 리턴되므로 위 코드를 사용.
		} else {
			return result;
			// 정보가 이미 있기 때문에 result를 리턴함.
		}
        
	}

바뀐 내용

  • 리턴타입 : HashMap<String, Object> 에서 KakaoDTO 로 변경.
  • catch문 아래에 코드 추가.

리턴 타입이 바뀌었으니 Controller의 getUserInfo 를 호출하는 코드의 타입을 바꿔줘야합니다.


Controller에 getUserInfo 호출하는 변수 타입 변경

@RequestMapping(value="/kakaoLogin", method=RequestMethod.GET)
public String kakaoLogin(@RequestParam(value = "code", required = false) String code) throws Exception {
	System.out.println("#########" + code);
	String access_Token = ms.getAccessToken(code);
    
	// userInfo의 타입을 KakaoDTO로 변경 및 import.
	KakaoDTO userInfo = ms.getUserInfo(access_Token);
    
	System.out.println("###access_Token#### : " + access_Token);
	System.out.println("###nickname#### : " + userInfo.get("nickname"));
	System.out.println("###email#### : " + userInfo.get("email"));
	return "member/testPage";
}

바뀌내용

  • 변경 전
HashMap<String, Object> userInfo = ms.getUserInfo(access_Token);
  • 변경 후
KakaoDTO userInfo = ms.getUserInfo(access_Token);

이제 Repository로 넘어갑시다.


Repository 생성 및 메서드 작성

  • Service에 Repository 메서드를 호출하는 코드를 작성했으므로 Repository와 메서드를 생성해줍시다.
package com.spring.project.repository;

import java.util.HashMap;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.spring.project.dto.KakaoDTO;

@Repository
public class MemberRepository {

	// mapper를 호출하기 위한 클래스 주입.
	@Autowired
	private SqlSessionTemplate sql;
	
	// 정보 저장
	public void kakaoinsert(HashMap<String, Object> userInfo) {
		sql.insert("Member.kakaoInsert",userInfo);
	}

	// 정보 확인
	public KakaoDTO findkakao(HashMap<String, Object> userInfo) {
		System.out.println("RN:"+userInfo.get("nickname"));
		System.out.println("RE:"+userInfo.get("email"));
		return sql.selectOne("Member.findKakao", userInfo);
	}

}

Repository를 다 작성했으니 mapper를 만들러 가봅시다.


mapper 생성 및 코드 작성

  • 저는 이름이 member-mapper로 xml파일을 생성했습니다.

  • mabatis에서 KakaoDTO를 kdto로 선언했습니다.

  • mapper에 주석이 있으면 오류가 뜨므로 주석은 복붙 뒤 지워주세요.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 
<mapper namespace="Member"> 

	<!-- 정보 찾기 -->
	<select id="findKakao" parameterType="java.util.HashMap" resultType="kdto">
		select * from kakao_table where k_name=#{nickname} and k_email=#{email}
	</select>

	<!-- 정보 저장 -->
	<insert id="kakaoInsert" parameterType="java.util.HashMap">
		insert into kakao_table(k_name, k_email)
			values(#{nickname}, #{email})
	</insert>
	
</mapper>

Controller에 가져온 정보 담기

  • 정보 저장 및 가져오는것까지 했으니 담는 코드를 짭시다.
    여기서는 session에 담는것까지만 진행하겠습니다. 여러분들은 각자 목적에 맞게 변경하세요.
// HttpSession 클래스 주입.
@Autowired
private HttpSession session;

@RequestMapping(value="/kakaoLogin", method=RequestMethod.GET)
public String kakaoLogin(@RequestParam(value = "code", required = false) String code) throws Exception {
	System.out.println("#########" + code);
	String access_Token = ms.getAccessToken(code);
	KakaoDTO userInfo = ms.getUserInfo(access_Token);
	System.out.println("###access_Token#### : " + access_Token);
	System.out.println("###nickname#### : " + userInfo.get("nickname"));
	System.out.println("###email#### : " + userInfo.get("email"));
    
	// 아래 코드가 추가되는 내용
	session.invalidate();
	// 위 코드는 session객체에 담긴 정보를 초기화 하는 코드.
	session.setAttribute("kakaoN", userInfo.getK_name())
	session.setAttribute("kakaoE", userInfo.getK_email());
	// 위 2개의 코드는 닉네임과 이메일을 session객체에 담는 코드
	// jsp에서 ${sessionScope.kakaoN} 이런 형식으로 사용할 수 있다.
    
    // 리턴값은 용도에 맞게 변경하세요~
	return "member/testPage";
}

마치며

여기까지 잘 따라오셨다면 카카오 로그인 및 DB에 저장까지 잘 될겁니다.
개인적으로 공부해서 정리한 내용을 올리는것으로 완벽하지는 않지만 참고용으로 활용해주시면 감사하겠습니다.

profile
즐겁다!

4개의 댓글

comment-user-thumbnail
2022년 5월 13일

안녕하세요. api 공부하다가 내용보면서 따라하고 있습니다. 코드는 다 작성했는데
질문이 여러개 있습니다.
1. mapper.xmlsms com.kako.demo 패키지가 아닌 src/main/resources/mapper 폴더에 넣으셨나요?
2. member-mapper.xml을 스캔을 잘 못하고 있는데 kakaologinApplication.java에서 @MapperScan(basePackages ??? ) basePackages 명을 뭐라 주면될까요??
Consider defining a bean of type 'org.mybatis.spring.SqlSessionTemplate' in your configuration.
에러가 뜨는데 member-mapper.xml을 제대로 스캔 못하고 있어서요
3. mapper 인터페이스가 위에 빠졌는데 하나 만들어 주실 수 있으신가요??

1개의 답글
comment-user-thumbnail
2022년 12월 27일

이 글로 인해서 kakao API 에 대해서 알게 되었습니다. 다른 어떤 글보다도 상세하고 자세한 설명 덕분에 프로젝트에 도움이 많이 되었습니다. 정말 감사합니다.

1개의 답글