Spring 카카오 로그인 DB저장하기!
Spring 에서 카카오 로그인 정보를 DB에 저장하는 방법을 정리해볼려고 합니다.
이전 카카오 로그인 REST API에서 추가로 몇가지만 작성하면 되므로 참고해주세요.
- 참고사항 (필독!)
- DB : MySQL
- 사용 tool : Spring Framework
- ☭ Spring 카카오 로그인 REST API 보러가기
- 제가 프로젝트를 진행하며 정리하는 내용이므로 완벽하지 않습니다, 참고용으로만 봐주세요!
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로 지정합니다.
package com.spring.project.dto;
import lombok.Data;
@Data
public class KakaoDTO {
private long k_number;
private String k_name;
private String k_email;
}
// 클래스 주입.
@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 를 호출하는 코드의 타입을 바꿔줘야합니다.
@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로 넘어갑시다.
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를 만들러 가봅시다.
저는 이름이 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>
// 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에 저장까지 잘 될겁니다.
개인적으로 공부해서 정리한 내용을 올리는것으로 완벽하지는 않지만 참고용으로 활용해주시면 감사하겠습니다.
안녕하세요. 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 인터페이스가 위에 빠졌는데 하나 만들어 주실 수 있으신가요??