새소식

반응형
250x250
📁 프로젝트 일지/🔎 기능 구현

카카오 로그인 API (2) - 간편 가입/로그인 기능 구현하기

  • -
728x90
반응형

https://hyewonkim1996.tistory.com/54

 

카카오 로그인 API (1) - 자바스크립트에 API 가져오기

1️⃣ 카카오 developers에서 애플리케이션 추가 링크 접속 👉 애플리케이션 추가하기 👉 정보 입력 👉 저장 https://developers.kakao.com/console/app 2️⃣ 메뉴 - 카카오 로그인 설정 생성한 애플리케이션

hyewonkim1996.tistory.com

지난번 자바스크립트에 카카오 API를 불러오는 과정까지 마쳤다.

API를 가져왔으면 이제 간편 가입과 로그인 기능을 구현해야 하는데, 문제가 있다.

카카오 심사를 거친 기업이 아니면 카카오 간편 가입 기능을 갖다 쓸 수 없다.

즉, 내가 알아서 구현해야 한다는 것.

 

자, 간편 가입/로그인이란 무엇일까.

필요한 회원 정보를 입력하지 않아도 알아서 회원 가입/로그인이 된다는 소리다.

즉 서버에서 회원 정보를 알아서 설정해 넘겨줘야 한다.

여기서 카카오 API로 가져온 정보를 보자.

 

 

<script>
//카카오로그인
function kakaoLogin() {
    Kakao.Auth.login({
      success: function (response) {
        Kakao.API.request({
          url: '/v2/user/me',
          success: function (response) {
        	  console.log(response) //이부분에서 정보를 볼수있다
          },
          fail: function (error) {
            console.log(error)
          },
        })
      },
      fail: function (error) {
        console.log(error)
      },
    })
  }
</script>

 

지난번 js에 적은 카카오 로그인 함수를 보면, 카카오 로그인 API 호출 성공 시 콘솔에서 응답 데이터를 확인할 수 있다.

카카오 로그인 버튼을 누르고 화면이 떴을 때 콘솔을 보면 이런 내용이 나온다.

id : ~~~~

nickname : ~~~~

내 카카오 아이디와 닉네임 정보를 API를 통해 가져왔다는 소리다.

현재 나의 웹 서비스에서 가입 시 필요한 회원 정보는 아이디, 비밀번호, 이름, 연락처다.

그러면 여기서 카카오 아이디 - 아이디, 닉네임 - 이름과 같이 내 서비스 회원가입에 필요한 정보로 바꿀 수 있겠다.

 

<script>
//카카오로그인
function kakaoLogin() {
    Kakao.Auth.login({
      success: function (response) {
        Kakao.API.request({
          url: '/v2/user/me',
          success: function (response) {
        	  //내 카카오 계정 id, 닉네임 : response의 내용을 변수에 저장
        	  const userId = response.id;
              const nickname = response.properties.nickname;
              //객체 변수에 저장, 변수명은 MemberVO에 매핑될수 있도록 필드명과 동일하게 작성
              const user = {m_id:userId,m_pw:'',m_name:nickname,m_phone:''};
          },
          fail: function (error) {
            console.log(error)
          },
        })
      },
      fail: function (error) {
        console.log(error)
      },
    })
  }
</script>

들여쓰기가 코드블럭 작성에는 반영되는데 확인 누르면 왜인지 반영이 안됨.. 양해 부탁

 

위와 같이 말이다.

문제는 회원가입에 비밀번호와 연락처 정보가 마저 필요한데, API에서 비밀번호와 연락처는 가져올 수 없다.

회원에게 입력하라고 할 수는 없으니, 그렇다면 임의로 설정해 서버로 보내는 수밖에 없다.

 

<script>
//카카오로그인
function kakaoLogin() {
    Kakao.Auth.login({
      success: function (response) {
        Kakao.API.request({
          url: '/v2/user/me',
          success: function (response) {
        	  //내 카카오 계정 id, 닉네임 : response의 내용을 변수에 저장
        	  const userId = response.id;
              const nickname = response.properties.nickname;
              //객체 변수에 저장, 변수명은 MemberVO에 매핑될수 있도록 필드명과 동일하게 작성
              const user = {m_id:userId,m_pw:'sns',m_name:nickname,m_phone:'연락처 미등록'};
          },
          fail: function (error) {
            console.log(error)
          },
        })
      },
      fail: function (error) {
        console.log(error)
      },
    })
  }
</script>

 

비밀번호와 연락처를 위와 같이 임의로 설정했다.

연락처의 경우 회원정보 수정에서 수정할 수 있게 하면 되니 문제가 없다.

아이디와 비밀번호도 다른 회원과 겹치지만 않는다면 문제가 없는데, 겹칠 일은 확실하게 없다.

기존 홈페이지 회원가입자의 경우 유효성 체크를 통해 영문 형식의 이메일과 8자 이상의 비밀번호만 설정할 수 있기 때문이다.

비밀번호가 간단해서 보안상 문제가 될 수는 있겠지만, 어차피 정식 서비스라면 간편 가입 API를 사용할 것이고, 저것은 로컬에서 구현하기 위한 임시 방편일 뿐이다.

 

이제 본격적으로 간편 가입/로그인 기능을 구현할 차례다.

그러려면 먼저 이 사람이 회원인지 아닌지를 알아야 한다.

그래야 간편 가입을 먼저 할지, 아니면 가입을 생략하고 로그인을 할지 판별할 수 있기 때문이다.

그리고 이 과정은 새로운 http 페이지로 넘어가서 이뤄지는 것이 아니라, 카카오 로그인 화면에서 다음 버튼을 누름과 동시에 진행되어야 한다.

즉, 동기가 아닌 비동기로 처리해야 한다.

 

<script>
//카카오로그인
function kakaoLogin() {
    Kakao.Auth.login({
      success: function (response) {
        Kakao.API.request({
          url: '/v2/user/me',
          success: function (response) {
        	  //내 카카오 계정 id, 닉네임 : response의 내용을 변수에 저장
        	  const userId = response.id;
              const nickname = response.properties.nickname;
              //객체 변수에 저장, 변수명은 MemberVO에 매핑될수 있도록 필드명과 동일하게 작성
              const user = {m_id:userId,m_pw:'sns',m_name:nickname,m_phone:'연락처 미등록'};
              $.ajax({
          		url:'userlist/'+userId,//카카오 id url에 붙여서 전송
          		method:'GET',
          		contentType : "application/json; charset=UTF-8", //서버로 보내는 데이터 타입(json)
          },
          fail: function (error) {
            console.log(error)
          },
        })
      },
      fail: function (error) {
        console.log(error)
      },
    })
  }
</script>

 

카카오 로그인 버튼을 누른 사용자가 회원인지 아닌지 판별하려면,

사용자의 카카오 아이디를 파라미터로 가져가 회원 조회 쿼리를 실행해야 한다.

따라서 ajax를 열고 url에 카카오 아이디를 파라미터로 붙이고, 메소드를 get으로 설정한다.

그러면 js에서 전송한 데이터는 url과 값이 일치하는 컨트롤러에 매핑될 것이다.

그 후 컨트롤러에서 회원 조회 쿼리로 회원 여부를 판별하고, 결과 데이터를 js에 다시 알려줘야 한다.

어떤 식으로 알려줘야 할까?

 

//회원 조회 메소드
	@GetMapping("/userlist/{userid}")//{userid} = ajax url에 붙인 값(ajax에서 쓴것과 이름 같아야 매핑됨)
	public String loginPreChk(@PathVariable String userid) {//url에 붙인 값(ajax에서 쓴것과 이름 같아야 매핑됨)
		MemberVO returnmvo = memberservice.selectOneforModify(userid); //회원 조회 쿼리 실행
		if(returnmvo!=null) {//MemberVO 객체가 null이 아님 = 디비에 존재하므로 이미 가입된 아이디
			return "login"; //ajax에 전달될 result
		}else {//MemberVO 객체가 null = 디비에 존재하지 않으므로 가입되지 않은 아이디
			return "signup";//ajax에 전달될 result
		}
	}

 

내가 선택한 방법은 위와 같다.

회원이면 login, 회원이 아니면 signup 하라고 직관적으로 문자를 리턴해 주었다.

이제 js에서 해당 데이터를 다시 받아 로그인과 회원가입 처리를 할 차례다.

 

<script>
//카카오로그인
function kakaoLogin() {
    Kakao.Auth.login({
      success: function (response) {
        Kakao.API.request({
          url: '/v2/user/me',
          success: function (response) {
        	  //내 카카오 계정 id, 닉네임 : response의 내용을 변수에 저장
        	  const userId = response.id;
              const nickname = response.properties.nickname;
              //객체 변수에 저장, 변수명은 MemberVO에 매핑될수 있도록 필드명과 동일하게 작성
              const user = {m_id:userId,m_pw:'sns',m_name:nickname,m_phone:'연락처 미등록'};
              $.ajax({
          		url:'userlist/'+userId,//카카오 id url에 붙여서 전송
          		method:'GET',
          		contentType : "application/json; charset=UTF-8", //서버로 보내는 데이터 타입(json)
                dataType : 'text', //서버로부터 받을 데이터 타입
          		success: function(result){
          			console.log(result);
          			if(result==='login'){//이미 가입된 카카오 id라면 로그인 진행
              		  console.log('로그인 진행');
              		  var password = "sns";
          			//아이디와 비밀번호를 post 방식으로 서버에 전송해야 하므로 동적 form 생성
          },
          fail: function (error) {
            console.log(error)
          },
        })
      },
      fail: function (error) {
        console.log(error)
      },
    })
  }
</script>

 

컨트롤러에서 보내는 데이터가 문자열이므로 datatype을 text로 설정했다.

먼저 'login'을 리턴받았을 경우 어떻게 로직을 작성해야 할까?

보통 우리가 로그인을 하면 사용자는 html form에 아이디와 비번을 적고, form에 적은 데이터를 post 방식으로 서버에 전달한다.

따라서 카카오 회원의 아이디와 비밀번호도 form에 넣어 보내기 위해 form을 동적으로 생성할 것이다.

 

<script>
//카카오로그인
function kakaoLogin() {
    Kakao.Auth.login({
      success: function (response) {
        Kakao.API.request({
          url: '/v2/user/me',
          success: function (response) {
        	  //내 카카오 계정 id, 닉네임 : response의 내용을 변수에 저장
        	  const userId = response.id;
              const nickname = response.properties.nickname;
              //객체 변수에 저장, 변수명은 MemberVO에 매핑될수 있도록 필드명과 동일하게 작성
              const user = {m_id:userId,m_pw:'sns',m_name:nickname,m_phone:'연락처 미등록'};
              $.ajax({
          		url:'userlist/'+userId,//카카오 id url에 붙여서 전송
          		method:'GET',
          		contentType : "application/json; charset=UTF-8", //서버로 보내는 데이터 타입(json)
                dataType : 'text', //서버로부터 받을 데이터 타입
          		success: function(result){
          			console.log(result);
          			if(result==='login'){//이미 가입된 카카오 id라면 로그인 진행
              		  console.log('로그인 진행');
              		  var password = "sns";
          			//아이디와 비밀번호를 post 방식으로 서버에 전송해야 하므로 동적 form 생성
                     // FormData 객체 생성
              		  var formData = new FormData();
          			//append 함수로 form에 작성할 데이터 붙이기(input 태그 name, input 태그 value)
              		  formData.append("m_id", userId);
              		  formData.append("m_pw", password);

              		  // 폼 동적 생성
              		  var form = document.createElement("form");
              		  form.method = "POST"; //폼의 메소드
              		  form.action = "login";  //클라이언트 요청 url(컨트롤러 value)

              		  // FormData를 폼에 추가
              		  for (var pair of formData.entries()) {
              		    var input = document.createElement("input");
              		    input.type = "hidden";
              		    input.name = pair[0]; //input 태그의 name 설정 : formData의 첫번째 요소(m_id, m_pw)
              		    input.value = pair[1];//input 태그의 value 설정 : formData의 두번째 요소(userId, password)
              		    form.appendChild(input);//폼에 자식 태그 추가(input)
              		  }

              		  // 폼을 body 태그의 자식으로 추가하고 전송
              		  document.body.appendChild(form);
              		  form.submit();
          },
          fail: function (error) {
            console.log(error)
          },
        })
      },
      fail: function (error) {
        console.log(error)
      },
    })
  }
</script>

 

먼저 form에 넣을 데이터와 데이터를 담을 input 태그가 필요하다.

이때 input 태그 name이 VO에 매핑될 수 있도록 VO 필드명과 동일하게 설정하는 것을 잊지 말자.

다음은 form이 필요하다.

도큐먼트의 요소에 form을 추가하고, 메소드를 post, url을 로그인 처리하는 컨트롤러와 매핑한다.

다음은 input 태그를 form에 넣어야 한다.

input 태그를 도큐먼트의 요소로 추가하고, name과 value를 설정한 후 form 태그의 자식으로 명시해 준다.

다음은 form 태그를 body에 넣어야 한다.

form을 body 자식으로 명시한 후, form을 제출하면 끝이다.

그러면 해당 form에 담긴 데이터는 post 방식으로 컨트롤러에 전달되고,

컨트롤러에서는 회원 조회 쿼리로 로그인 처리를 해준다.(내 경우는 시큐리티가 대신 해준다.)

 

 

그러면 사용자가 기존 회원이 아닐 경우에는? 회원가입 처리를 해야 한다.

 

<script>
//카카오로그인
function kakaoLogin() {
    Kakao.Auth.login({
      success: function (response) {
        Kakao.API.request({
          url: '/v2/user/me',
          success: function (response) {
        	  //내 카카오 계정 id, 닉네임 : response의 내용을 변수에 저장
        	  const userId = response.id;
              const nickname = response.properties.nickname;
              //객체 변수에 저장, 변수명은 MemberVO에 매핑될수 있도록 필드명과 동일하게 작성
              const user = {m_id:userId,m_pw:'sns',m_name:nickname,m_phone:'연락처 미등록'};
              $.ajax({
          		url:'userlist/'+userId,//카카오 id url에 붙여서 전송
          		method:'GET',
          		contentType : "application/json; charset=UTF-8", //서버로 보내는 데이터 타입(json)
                dataType : 'text', //서버로부터 받을 데이터 타입
          		success: function(result){
          			console.log(result);
          			if(result==='login'){//이미 가입된 카카오 id라면 로그인 진행
              		  console.log('로그인 진행');
              		  var password = "sns";
          			//아이디와 비밀번호를 post 방식으로 서버에 전송해야 하므로 동적 form 생성
                     // FormData 객체 생성
              		  var formData = new FormData();
          			//append 함수로 form에 작성할 데이터 붙이기(input 태그 name, input 태그 value)
              		  formData.append("m_id", userId);
              		  formData.append("m_pw", password);

              		  // 폼 동적 생성
              		  var form = document.createElement("form");
              		  form.method = "POST"; //폼의 메소드
              		  form.action = "login";  //클라이언트 요청 url(컨트롤러 value)

              		  // FormData를 폼에 추가
              		  for (var pair of formData.entries()) {
              		    var input = document.createElement("input");
              		    input.type = "hidden";
              		    input.name = pair[0]; //input 태그의 name 설정 : formData의 첫번째 요소(m_id, m_pw)
              		    input.value = pair[1];//input 태그의 value 설정 : formData의 두번째 요소(userId, password)
              		    form.appendChild(input);//폼에 자식 태그 추가(input)
              		  }

              		  // 폼을 body 태그의 자식으로 추가하고 전송
              		  document.body.appendChild(form);
              		  form.submit();
          			}else{//가입되지 않은 카카오 id라면(result==='signup')
              		  console.log('회원가입 진행');
              		  signup(user);//회원정보(카카오 id, 임시 비번, 카카오 닉네임, 임시 연락처)를 가지고 회원가입 함수 호출
              	  },
          fail: function (error) {
            console.log(error)
          },
        })
      },
      fail: function (error) {
        console.log(error)
      },
    })
  }
</script>

 

위와 같이 else절 = 로그인이 아닐 경우(signup) 회원가입 로직을 실행한다.

코드가 너무 길어져 가독성을 위해 signup 함수를 따로 작성하기로 했다.

설정한 회원 정보를 가지고 signup 함수를 호출한다.

이제 signup 함수에 회원가입 비동기 처리만 해주면 된다.

//회원가입 함수
function signup(user){
	 $.ajax({
    	 url:'user',
    	 method:'POST',
    	 data:JSON.stringify(user),
    	 contentType:"application/json; charset=UTF-8",
    	 success:function(result){
    		 alert("회원가입이 완료되었습니다.\n카카오 로그인을 다시 눌러 주세요.");
    	 },
    	 error:function(){
    		 alert("오류");
    	 }
      });
}

 

post 메소드로 컨트롤러에 데이터를 전달한다.

 

@Inject
MemberService memberservice;
//회원가입 메소드
@PostMapping("/user")
public String join(@RequestBody MemberVO mvo) {//ajax에서 전송한 data MemberVO에 매핑
	if(mvo.getM_id()!=null) {//MemberVO 객체 id가 null이 아니다 = 매핑 성공
		memberservice.insertOne(mvo); //회원 insert 쿼리 진행
		return "success";
	}else {
		return "mvo is null";
	}
}

 

컨트롤러에서 insert 쿼리를 실행한다.

insert 쿼리가 실행되면 간편 가입이 완료되고 회원에게 안내 메시지를 띄웠다.

 

 

 

즉 최초 클릭 시 자동 회원가입 -> 재클릭 시 자동 로그인으로 진행된다.

728x90
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.