Spring - 카카오톡 로그인 기능 구현 하기 -3

2021. 5. 11. 09:17Java/Spring

반응형

지난 장에 이어서 이번에는 백단 처리를 해보자

 

우선 DB에 카카오 로그인 여부를 기록할 컬럼을 만든다.

해당 컬럼에 카카오에서 보내는 개인 고유 id를 기록한다.

 

DB작업은 해당 컬럼만 생성해주면 된다.

 

이제 코드를 작성해야한다. 먼저 지난장에 작성한 데이터를 보내는 아작스는 아래와 같다.

 

function kakaoLoginPro(response){
	var data = {id:response.id,email:response.kakao_account.email}
	$.ajax({
		type : 'POST',
		url : '/user/kakaoLoginPro.do',
		data : data,
		dataType : 'json',
		success : function(data){
			console.log(data)
			if(data.JavaData == "YES"){
				alert("로그인되었습니다.");
				location.href = '/user/usermain.do'
			}else if(data.JavaData == "register"){
				$("#kakaoEmail").val(response.kakao_account.email);
				$("#kakaoId").val(response.id);
				$("#kakaoForm").submit();
			}else{
				alert("로그인에 실패했습니다");
			}
			
		},
		error: function(xhr, status, error){
			alert("로그인에 실패했습니다."+error);
		}
	});
	
}

/user/kakaoLoginPro.do 해당 요청을 받는 스프링 코드는 아래와 같다.

 

@RequestMapping(value="/kakaoLoginPro.do", method=RequestMethod.POST)
	public Map<String, Object> kakaoLoginPro(@RequestParam Map<String,Object> paramMap,HttpSession session) throws SQLException, Exception {
		System.out.println("paramMap:" + paramMap);
		Map <String, Object> resultMap = new HashMap<String, Object>();
		
		Map<String, Object> kakaoConnectionCheck = userservice.kakaoConnectionCheck(paramMap);
		if(kakaoConnectionCheck == null) { //일치하는 이메일 없으면 가입
			resultMap.put("JavaData", "register");
		}else if(kakaoConnectionCheck.get("KAKAOLOGIN") == null && kakaoConnectionCheck.get("EMAIL") != null) { //이메일 가입 되어있고 카카오 연동 안되어 있을시
			System.out.println("kakaoLogin");
			userservice.setKakaoConnection(paramMap);
			Map<String, Object> loginCheck = userservice.userKakaoLoginPro(paramMap);
			session.setAttribute("userInfo", loginCheck);
			resultMap.put("JavaData", "YES");
		}else{
			Map<String, Object> loginCheck = userservice.userKakaoLoginPro(paramMap);
			session.setAttribute("userInfo", loginCheck);
			resultMap.put("JavaData", "YES");
		}
		
		return resultMap;
	}

이전에 작성한 네이버와 마찬가지로 기존 일치하는 이메일이 없으면 새로 가입, 카카오 로그인 기록이 없으면 카카오 로그인 컬럼에 데이터 추가, 기존에 카카오 로그인 했으면 로그인을 해준다.

 

해당 부분에 대한 로직은 네이버 로그인과 같아 아래 글을 참고하면 된다.

cookinghoil.tistory.com/100?category=905374

 

 

만약 카카오 로그인한 유저가 첫 가입이라면 추가 정보를 입력해야한다.

 

그러기 위해서 "register"라고 앞단에 다시 보내주는데 이 것을 ajax 에서 아래와 같이 처리했다.

 

 

form에다가 유저 정보를 입력해서 submit을 시켜서 페이지 이동을 시켰는데 해당 폼은 input hidden으로 아래처럼 이루어져있다.

 

<form name="kakaoForm" id="kakaoForm" method = "post" action="/user/setSnsInfo.do">
<input type="hidden" name="email" id="kakaoEmail" />
<input type="hidden" name="id" id="kakaoId" />
<input type="hidden" name="flag" id="flag" value="kakao" />
</form>

가입 유저의 기본정보를 입력하고 /user/setSnsInfo.do 으로 요청을 보낸다.

 

해당 부분을 보면 아래와 같다.

 

@RequestMapping(value="setSnsInfo.do")
	public String setKakaoInfo(Model model,HttpSession session,@RequestParam Map<String,Object> paramMap) {
		System.out.println("setKakaoInfo");	
		System.out.println("param ==>"+paramMap);
		
		model.addAttribute("email",paramMap.get("email"));
		model.addAttribute("password",paramMap.get("id"));
		model.addAttribute("flag",paramMap.get("flag"));
		return "user/setSnsInfo";
	}

컨트롤러를 통해서 기본 정보를 보내주며 페이지 이동을 한다.

 

이동한 페이지의 코드는 아래와 같이 넘겨받은 기본 정보 email,id등은 hidden으로 기본적으로 입력하고,

 

추가 정보만 받는다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<link rel="stylesheet" type="text/css" href="/css/userRegister.css?version=21042510" />
<form name="userRegisterForm" id="userRegisterForm" method="POST">
	<input type="hidden"  id="email" name="email" value="${email}"/>
	<input type="hidden"  id="password" name="password"  value="${password}">
	<input type="hidden"  id="id" name="id"  value="${password}">
	<input type="hidden"  id="flag" name="flag"  value="${flag}">
	<c:if test="${phone != null && phone != ''}">
	<input type="hidden"  id="phone" name="phone"  value="${phone}">
	</c:if>
	
	<table>
		<thead>
			<tr>
				<th colspan="3">신규 가입 추가 정보 설정</th>
			</tr>
		</thead>
		<tbody>
			
			<tr>
				<td class="text">닉네임</td>
				<td>
					<input id="nicknameCheck" name="nicknameCheck">
					<input type="hidden" id="nickname" name="nickname">
				</td>
				<td><button id="dupliButton" type="button" onclick="checkNickname()">중복체크</button></td>
			</tr>
		<c:if test="${phone == null || phone == ''}">
			<tr>
				<td class="text">전화번호</td>
				<td>
					<input id="phone" name="phone">
				</td>
				<td></td>
			</tr>
		</c:if>
			<tr>
				<td></td>
				<td><input type="button" id="regiButton" onclick="register()" value="회원가입" /></td>
				<td></td>
			</tr>
		</tbody>
	</table>
</form>
<script>
function checkNickname(){
	var nicknameCheck = $("#nicknameCheck").val();
	var nickname = $("#nickname").val();
	var regExp =  /^[가-힣|a-z|A-Z|0-9|]+$/;

	if(nicknameCheck == null || nicknameCheck == ""){
		alert("닉네임을 입력 해주세요");
		return false;
	}
	if(!regExp.test(nicknameCheck)){
		alert("닉네임은 한글, 영어, 숫자만 4 ~10자리로 입력 가능합니다.");
		return false;
	}
	$.ajax({
		type : 'POST',
		url : '/user/checkNickname.do',
		data : {nickname:nicknameCheck },
		dataType : 'json',
		success : function(data){
			console.log(data)
			if(data.JavaData == 'YES'){
				alert("사용가능한 닉네임 입니다.");
				$("#nickname").val(nicknameCheck);
			}else{
				alert("이미 존재하는 닉네임 입니다.");
				$("#nicknameCheck").val("");
			}
		},
		error: function(xhr, status, error){
			alert(error);
		}
	});
}


function register(){
	var registerData =common.serializeObject($("form[name=userRegisterForm]"));
	if(registerData.nickname == null || registerData.nickname == ""){
		alert("닉네임 중복 체크를 해주세요");
		return false;
	}
	if(registerData.phone == null || registerData.phone == ""){
		alert("번호를 입력하세요");
		$("#phone").focus();
		return false;
	}
	var phoneRegExp = /^\d{3}-\d{3,4}-\d{4}$/;
	var telRegExp = /^\d{2,3}-\d{3,4}-\d{4}$/;
	var phoneNum = registerData.phone.replace(/(^02.{0}|^01.{1}|[0-9]{3})([0-9]+)([0-9]{4})/,"$1-$2-$3")
	if(!phoneRegExp.test(phoneNum) && !telRegExp.test(phoneNum)){
		alert("올바른 번호 형식을 입력하세요");
		return false;
	}
	
	
	$.ajax({
		type : 'POST',
		url : '/user/userSnsRegisterPro.do',
		data : registerData,
		dataType : 'json',
		success : function(data){
			if(data.JavaData == "YES"){
				alert("가입되었습니다.");
				location.href = '/user/usermain.do'
			}else{
				alert("가입에 실패했습니다.");
			}
		},
		error: function(xhr, status, error){
			alert("가입에 실패했습니다."+error);
		}
	});
}
</script>

여기서 flag의 값을 받는데 이는 네이버 로그인, 카카오 로그인, 구글 로그인을 백엔드에서 구분해주기 위해서이다.

해당 요청을 받는 스프링 코드는 아래와 같다.

 

@RequestMapping(value="/userSnsRegisterPro.do", method=RequestMethod.POST)
	public Map<String, Object> userSnsRegisterPro(@RequestParam Map<String,Object> paramMap,HttpSession session) throws SQLException, Exception {
		System.out.println("paramMap:" + paramMap);
		Map <String, Object> resultMap = new HashMap<String, Object>();
		String flag = (String) paramMap.get("flag");
		Integer registerCheck = null;
		if(flag.equals("kakao")) {
			registerCheck = userservice.userKakaoRegisterPro(paramMap);
		}else if(flag.equals("google")) {
			registerCheck = userservice.userGoogleRegisterPro(paramMap);
		}else if(flag.equals("naver")) {
			registerCheck = userservice.userNaverRegisterPro(paramMap);
		}
		
		
		if(registerCheck != null && registerCheck > 0) {
			Map<String, Object> loginCheck = null;
			if(flag.equals("kakao")) {
				loginCheck = userservice.userKakaoLoginPro(paramMap);
			}else if(flag.equals("google")) {
				loginCheck = userservice.userGoogleLoginPro(paramMap);
			}else if(flag.equals("naver")) {
				loginCheck = userservice.userNaverLoginPro(paramMap);
			}
			 
			session.setAttribute("userInfo", loginCheck);
			resultMap.put("JavaData", "YES");
		}else {
			resultMap.put("JavaData", "NO");
		}
		return resultMap;
	}

위 코드와 같이 flag의 값으로 어떤 가입인지 구분하여 가입하고 로그인한다.

 

 

위와 같이 구현하면 정상적으로 가입 및 로그인이 이루어진다.

반응형