지난번 팝업을 이용한 카카오로그인에 대해 간단한게 살펴보았다.
이번에는 REST API 를 이용한 카카오로그인에 대해 알아보도록 하자
기본적으로 REST API 를 이용하기 위해선 PHP 스크립트를 실행할 수 있는 서버가 있어야하며
해당 서버가 준비가 안되었다면 이번 샘플을 실행할 수 없다. CURL 통신의 경우 LIB 파일로 제공하니
해당 파일을 참고하여 실 운영서버 개발 시 수정하여 사용하면 된다.
참고로 소스이외 샘플 파일로 다운로드할 경우 아래의 샘플파일을 먼저 다운로드 해보면된다.
<?php
/*
@ 카카오 로그인 REST API 샘플
© 2022 REDINFO <webmaster@redinfo.co.kr>
*/
session_start();
class kakaoRestAPI{
// <수정필요> REST API 키값 : kakao developers > 내 애플리케이션 > 요약정보 > 앱 키 > REST API 키\
var $restapi_key = '';
// <수정필요> 리다렉트 URL : kakao developers > 내 애플리케이션 > 제품설정 > 카카오 로그인 > Redirect URI
var $redirect_uri = '';
// <수정필요> 카카오 로그인 인증 후 이동할 페이지
var $result_uri = '';
// api 사용가능 여부
var $auth_apply = false;
// 디버깅시 결과 볼지 여부 (true or false)
var $debug_view = true;
// 디버깅시 결과 테스트 (true or false)
var $debug_txt = '';
// 요청 URL 정의
var $request_url = array(
'code'=>'https://kauth.kakao.com/oauth/authorize?response_type=code&client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}', // get
'token'=>'https://kauth.kakao.com/oauth/token', // 토큰 받기 // (only post)
'userInfo'=>'https://kapi.kakao.com/v2/user/me', // 사용자 정보 가져오기(get or post)
'logout'=>'https://kapi.kakao.com/v1/user/logout', // 사용자 로그아웃 가져오기(only post)
);
/*생성자*/
function __construct(){
if( empty($this->restapi_key)){ return $this->debug('restapi_key 키값 누락',__LINE__); }
if( empty($this->redirect_uri)){ return $this->debug('redirect_uri 값 누락',__LINE__); }
// request code url 치환자 정의
$this->request_url['code'] = str_replace(array('{REST_API_KEY}','{REDIRECT_URI}'),array($this->restapi_key,urlencode($this->redirect_uri)),$this->request_url['code']);
// api 사용가능 여부
$this->auth_apply = true;
}
/*token요청*/
function getToken($code){
// code 는 header 로 요청되기때문에 반드시 출력 전에 실행
if($this->auth_apply !== true){ return $this->debug("카카오 로그인 API를 호출할 수 없습니다.",__LINE__); }
if(empty($code)){ return $this->debug("인가코드가 누락되었습니다.",__LINE__); }
// URL에서 데이터를 추출하여 쿼리문 생성
$postfields = array('grant_type'=>'authorization_code','client_id'=>$this->restapi_key,'redirect_uri'=>$this->redirect_uri,'code'=>$code);
$url = $this->request_url['token']."?".http_build_query($postfields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$data = curl_exec($ch);
if (curl_error($ch)){ return $this->debug('통신에러 ('.curl_errno( $ch ).') '.curl_error($ch),__LINE__);}
curl_close($ch);
return $data;
}
/*사용자정보호출*/
function getUserInfo($access_token){
// code 는 header 로 요청되기때문에 반드시 출력 전에 실행
if($this->auth_apply !== true){ return $this->debug("카카오 로그인 API를 호출할 수 없습니다.",__LINE__); }
if(empty($access_token)){ return $this->debug("인증코드가 누락되었습니다.",__LINE__); }
// URL에서 데이터를 추출하여 쿼리문 생성
$url = $this->request_url['userInfo'];
$headers = array("Authorization: Bearer ".$access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$data = curl_exec($ch);
if (curl_error($ch)){ return $this->debug('통신에러 ('.curl_errno( $ch ).') '.curl_error($ch),__LINE__);}
curl_close($ch);
return $data;
}
/*로그아웃*/
function getLogout($access_token){
// code 는 header 로 요청되기때문에 반드시 출력 전에 실행
if($this->auth_apply !== true){ return $this->debug("카카오 로그인 API를 호출할 수 없습니다.",__LINE__); }
if(empty($access_token)){ return $this->debug("인증코드가 누락되었습니다.",__LINE__); }
// URL에서 데이터를 추출하여 쿼리문 생성
$url = $this->request_url['logout'];
$headers = array("Authorization: Bearer ".$access_token);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$data = curl_exec($ch);
if (curl_error($ch)){ return $this->debug('통신에러 ('.curl_errno( $ch ).') '.curl_error($ch),__LINE__);}
curl_close($ch);
return $data;
}
/*디버깅*/
function debug($msg,$code){
ob_start();
echo "[".$code."] ".$msg;
$this->debug_txt = ob_get_clean();
if( $this->debug_view === true){ echo $this->debug_txt; }
return false;
}
}
<?php
include_once dirname(__FILE__)."/lib.php";
$kakaologin = new kakaoRestAPI();
if( $kakaologin->auth_apply !== true){ die("카카오로그인을 사용할 수 없습니다."); }
$arrUserInfo = array('id'=>'','nickname'=>'','email'=>'','gender'=>'');
if(!empty($_SESSION['auth_kakao_user_info'])){
if( !empty($_SESSION['kakao_user_info']['id'])){ $arrUserInfo['id']= $_SESSION['kakao_user_info']['id']; }
if( !empty($_SESSION['kakao_user_info']['kakao_account']['profile']['nickname'])){ $arrUserInfo['nickname']= $_SESSION['kakao_user_info']['kakao_account']['profile']['nickname']; }
if( !empty($_SESSION['kakao_user_info']['kakao_account']['email'])){ $arrUserInfo['email']= $_SESSION['kakao_user_info']['kakao_account']['email']; }
if( !empty($_SESSION['kakao_user_info']['kakao_account']['gender'])){ $arrUserInfo['gender']= $_SESSION['kakao_user_info']['kakao_account']['gender']; }
}
?>
<div class="wrap-kakao-login">
<h1>카카오톡 API를 이용한 로그인 샘플(REST API)</h1>
<ul>
<li><a href="/kakao-login.php">처음화면으로</a></li>
<li><a href="<?php echo $kakaologin->redirect_uri; ?>?logout=true">로그아웃</a></li>
<li><a href="<?php echo $kakaologin->request_url['code'] ?>" class="kakao-login"><img src="//k.kakaocdn.net/14/dn/btroDszwNrM/I6efHub1SN5KCJqLm1Ovx1/o.jpg" width="180" alt="카카오 로그인 버튼"/></a></li>
</ul>
<h3>인증상태</h3>
<ul>
<li>토큰인증: <?php echo !empty($_SESSION['auth_kakao_token_info']) ? '<font color="blue">인증완료</font>':'<font color="red">인증대기</font>'; ?></li>
<li>사용자인증: <?php echo !empty($_SESSION['auth_kakao_user_info']) ? '<font color="blue">인증완료</font>':'<font color="red">인증대기</font>'; ?></li>
</ul>
<h3>인증후 사용자 정보(아이디(고유번호),이메일,닉네임,성별)</h3>
<ul>
<li>아이디(고유번호): <input type="text" name="id" value="<?php echo $arrUserInfo['id'] ?>"></li>
<li>닉네임: <input type="text" name="nickname" value="<?php echo $arrUserInfo['nickname'] ?>"></li>
<li>이메일: <input type="text" name="email" value="<?php echo $arrUserInfo['email'] ?>"></li>
<li>성별: <input type="text" name="gender" value="<?php echo $arrUserInfo['gender'] ?>"></li>
</ul>
</div>
<style>
.wrap-kakao-login{ padding:2%; }
.wrap-kakao-login li{ margin:10px 0; }
</style>
<?php
include_once dirname(__FILE__)."/lib.php";
$kakaologin = new kakaoRestAPI();
if( $kakaologin->auth_apply !== true){ die("카카오로그인을 사용할 수 없습니다."); }
// 로그아웃일경우
if( !empty($_GET['logout'])){
// 사용자 정보 호출
$userLogout = @json_decode($kakaologin->getLogout($_SESSION['kakao_token_info']['access_token']),true);
// 에러
if( !empty($userLogout['msg']) ){
echo '<h1>사용자 로그아웃 요청실패</h1><pre>'; print_r($userLogout); echo '</pre>';
exit;
}
if(!empty($_SESSION['auth_kakao_token_info'])) unset($_SESSION['auth_kakao_token_info'],$_SESSION['kakao_token_info']);
if(!empty($_SESSION['auth_kakao_user_info'])) unset($_SESSION['auth_kakao_user_info'],$_SESSION['kakao_user_info']);
die(header("Location:".$kakaologin->result_uri));
}
if(!empty($_SESSION['auth_kakao_token_info'])) unset($_SESSION['auth_kakao_token_info'],$_SESSION['kakao_token_info']);
if(!empty($_SESSION['auth_kakao_user_info'])) unset($_SESSION['auth_kakao_user_info'],$_SESSION['kakao_user_info']);
// 받은 코드로 처리
$code = empty($_GET['code']) ? '': $_GET['code'];
$token = @json_decode($kakaologin->getToken($code),true);
// 에러
if( !empty($token['error']) ){
echo '<h1>인증토큰 요청 실패</h1><pre>'; print_r($token); echo '</pre>';
exit;
}
// 세션에 토큰 정보를 저장
$_SESSION['auth_kakao_token_info'] = true;
$_SESSION['kakao_token_info'] = $token;
// 사용자 정보 호출
$userInfo = @json_decode($kakaologin->getUserInfo($token['access_token']),true);
// 에러
if( !empty($userInfo['msg']) ){
echo '<h1>사용자 정보 요청실패</h1><pre>'; print_r($userInfo); echo '</pre>';
exit;
}
// 세션에 사용자 정보를 저장
$_SESSION['auth_kakao_user_info'] = true;
$_SESSION['kakao_user_info'] = $userInfo;
// 사용자 정보 요청
die(header("Location:".$kakaologin->result_uri));