Final Project
[ Spring ] REST API로 카카오 로그인 구현하기 , DB에 저장하기 (동의 항목 선택 / 비선택 처리 )
HTT
2023. 1. 13. 00:18
* REST API를 이용해 Spring으로 카카로 로그인 구현하기 *
지난 게시글에서 받아온 회원 정보를 DB에 저장하고, 동의항목을 선택하지 않았을 때의 예외작업도 진행해보겠습니다.
(Spring과 MySQL을 사용)
간략한 순서는 아래와 같습니다.
1. 동의 항목 선택 여부 처리하기
2. DB에 데이터 저장하기
1. 동의 항목 선택 여부 처리
우선 지난번 작성했던 KakaoService.java 파일을 수정합니다.
💡 로그인 처리(KakaoService.java)
@Service
public class KakaoService {
CustomerDAO dao;
KakaoService() {};
@Autowired
public KakaoService(CustomerDAO dao) {
super();
this.dao = dao;
}
public String getToken(String code) throws IOException, org.json.simple.parser.ParseException {
// 인가코드로 토큰받기
String host = "https://kauth.kakao.com/oauth/token";
URL url = new URL(host);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
String token = "";
try {
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true); // 데이터 기록 알려주기
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(urlConnection.getOutputStream()));
StringBuilder sb = new StringBuilder();
sb.append("grant_type=authorization_code");
sb.append("&client_id=ce8affbe0709e40494b6d8ad31a694eb");
sb.append("&redirect_uri=http://localhost:8088/evweb/kakao");
sb.append("&code=" + code);
bw.write(sb.toString());
bw.flush();
int responseCode = urlConnection.getResponseCode();
System.out.println("responseCode 확인 = " + responseCode);
BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line = "";
String result = "";
while ((line = br.readLine()) != null) {
result += line;
}
System.out.println("result = " + result);
// json parsing
JSONParser parser = new JSONParser();
JSONObject elem = (JSONObject) parser.parse(result);
String access_token = elem.get("access_token").toString();
String refresh_token = elem.get("refresh_token").toString();
System.out.println("refresh_token = " + refresh_token);
System.out.println("access_token = " + access_token);
token = access_token;
br.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
return token;
}
//선택동의한 유저 정보 받아오기
public CustomerDTO getUserInfo(String access_token) throws IOException, org.json.simple.parser.ParseException {
String host = "https://kapi.kakao.com/v2/user/me";
HashMap<String, Object> result = new HashMap<String, Object>();
try {
// 1.url 객체만들기
URL url = new URL(host);
// 2.url 에서 url connection 만들기
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// 3.URL 연결구성
urlConnection.setRequestProperty("Authorization", "Bearer " + access_token);
urlConnection.setRequestMethod("GET");
//키값, 속성 적용
int responseCode = urlConnection.getResponseCode(); // 서버에서 보낸 http 상태코드 반환
System.out.println("responseCode = " + responseCode);
// responsecode가 200이 아닌 경우 if문을 통해서 예외처리 가능
BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
// 버퍼 사용해 읽기
String line = "";
String res = "";
while((line=br.readLine())!=null)
{
res+=line;
}
System.out.println("res = " + res);
// json으로 파싱하기
JSONParser parser = new JSONParser();
JSONObject obj = (JSONObject) parser.parse(res);
JSONObject kakao_account = (JSONObject) obj.get("kakao_account");
//JSONObject properties = (JSONObject) obj.get("properties"); //닉네임, 프로필이미지 ...
String id = obj.get("id").toString();
// 선택항목(이메일) 체크 여부 나눠서 처리
if(kakao_account.get("email")==null) {
result.put("id", id);
}else {
String email = kakao_account.get("email").toString();
result.put("id", id);
result.put("email", email);
}
//String birthday = kakao_account.get("birthday").toString();
//result.put("birthday", birthday);
br.close();
} catch (IOException e) {
e.printStackTrace();
}
CustomerDTO dtoresult = dao.findkakao(result);
System.out.println("dtoresult================> "+dtoresult);
// dtoresult null => 디비에 저장된 정보가 없음. 디비에 저장하기
if(dtoresult == null) {
// 선택항목(이메일) 체크 여부 나눠서 데이터저장하기
if(result.get("email")==null) {
dao.kakaoInsertNull(result);
}else {
dao.kakaoInsert(result);
}
// 정보 저장 후 컨트롤러에 데이터 보내기
return dao.findkakao(result);
//dtoresult를 리턴으로 보내면 null이 리턴되므로 위의 코드를 사용.
}else {
return dtoresult;
//정보가 있으므로 dtoresult를 리턴함
}
}
// 정상적으로 받아왔는지 여부
public String getAgreementInfo(String access_token)
{
String result = "";
String host = "https://kapi.kakao.com/v2/user/scopes";
try{
URL url = new URL(host);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("Authorization", "Bearer "+access_token);
BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line = "";
while((line=br.readLine())!=null)
{
result+=line;
}
int responseCode = urlConnection.getResponseCode();
System.out.println("responseCode = " + responseCode);
// result is json format
br.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
수정된 부분 2곳을 살펴보겠습니다.
① HashMap에 데이터 put하기
String id = obj.get("id").toString();
// 선택항목(이메일) 체크 여부 나눠서 처리
if(kakao_account.get("email")==null) {
result.put("id", id);
}else {
String email = kakao_account.get("email").toString();
result.put("id", id);
result.put("email", email);
}
kakao_acount에서 받아온 이메일 정보가 없다면 "id" 정보만 넣고, 이메일 정보가 있다면 추출해서 집어넣도록 했습니다. 개인에 따라 이메일이 아닌 다른 정보에 맞게 수정하시면 될 것 같습니다.
② DB에 데이터 넣기
CustomerDTO dtoresult = dao.findkakao(result);
System.out.println("dtoresult================> "+dtoresult);
// dtoresult null => 디비에 저장된 정보가 없음. 디비에 저장하기
if(dtoresult == null) {
// 선택항목(이메일) 체크 여부 나눠서 데이터저장하기
if(result.get("email")==null) {
dao.kakaoInsertNull(result);
}else {
dao.kakaoInsert(result);
}
// 정보 저장 후 컨트롤러에 데이터 보내기
return dao.findkakao(result);
//dtoresult를 리턴으로 보내면 null이 리턴되므로 위의 코드를 사용.
}else {
return dtoresult;
//정보가 있으므로 dtoresult를 리턴함
}
json파싱으로 꺼내와 HashMap에 저장한 데이터를 DTO타입으로 변환한 후, "null" 체크를 하여 DB에 저장하는 순서로 작업을 했습니다. 회원 테이블을 구성할 때 이메일 컬럼을 "NOT NULL"로 만들었기 때문에 "null"값을 넘기지 않도록 쿼리문을 2가지를 만들어 처리했습니다. 만약 이메일 정보가 있다면 [ kakaoInsert ] 메소드가 실행되며, 카카오에서 받아온 데이터를 저장하게 됩니다.
2. DB에 데이터 저장
이제 DAOImpl과 mapper작업을 해보겠습니다.
💡 DB작업(CustomerDAOImpl.java)
@Repository
public class CustomerDAOImpl implements CustomerDAO {
SqlSession sqlsession;
@Autowired
public CustomerDAOImpl(SqlSession sqlsession) {
super();
this.sqlsession = sqlsession;
}
@Override
public int kakaoInsert(HashMap<String, Object> userInfo) {
String customer_id = (String) userInfo.get("id");
String email = (String) userInfo.get("email");
CustomerDTO dto = new CustomerDTO();
dto.setCustomer_id(customer_id);
dto.setEmail(email);
return sqlsession.insert("com.project.customer.kakaoInsert",dto);
}
@Override
public CustomerDTO findkakao(HashMap<String, Object> userInfo) {
String customer_id = (String) userInfo.get("id");
String email = (String) userInfo.get("email");
CustomerDTO dto = new CustomerDTO();
dto.setCustomer_id(customer_id);
dto.setEmail(email);
return sqlsession.selectOne("com.project.customer.findkakao",dto);
}
// 이메일 == null
@Override
public int kakaoInsertNull(HashMap<String, Object> userInfo) {
String customer_id = (String) userInfo.get("id");
CustomerDTO dto = new CustomerDTO();
dto.setCustomer_id(customer_id);
return sqlsession.selectOne("com.project.customer.kakaoInsertNull",dto);
}
}
💡 DB작업(mapper.xml)
<insert id="kakaoInsert" parameterType="customer">
insert into CUSTOMER_TB values(
#{customer_id}, '정보없음',
'정보없음', '정보없음', '정보없음', '정보없음', '정보없음', #{email}, now(),
str_to_date('11111111','%Y%m%d'), '정보없음', '정보없음', '카카오')
</insert>
<insert id="kakaoInsertNull" parameterType="customer">
insert into CUSTOMER_TB values(
#{customer_id}, '정보없음',
'정보없음', '정보없음', '정보없음', '정보없음', '정보없음', '정보없음', now(),
str_to_date('11111111','%Y%m%d'), '정보없음', '정보없음', '카카오')
</insert>
<select id="findkakao" parameterType="customer" resultType="customer">
select * from CUSTOMER_TB where customer_id = #{customer_id}
</select>
위 과정이 문제없이 실행됐다면 정상적으로 회원가입/로그인이 되고, DB에도 데이터가 저장된 걸 확인할 수 있습니다.
※ 틀린 부분이 있을 수 있습니다.