평범한 이야기들

[PHP] 카카오 로그인 사용하기 본문

평범한 개발 이야기/PHP

[PHP] 카카오 로그인 사용하기

songsariya 2021. 8. 5. 10:55
728x90

 대부분 사이트에 붙어있는 간편 로그인 중 하나인 카카오를 이용한 로그인 방법을 정리합니다. 대부분 간편 로그인이 그렇듯 카카오 로그인은 OAuth 2.0을 기반으로 하고 있습니다. 

 

카카오 로그인이 진행되는 과정은 아래와 같습니다. 

카카오 로그인 진행 과정 (1)

카카오 로그인에 대한 자세한 문서는 카카오 개발자 사이트에서 참조하시기 바랍니다.

카카오 개발자 사이트 (카카오 로그인) : https://developers.kakao.com/docs/latest/ko/kakaologin/common

 

카카오 로그인에 사용한 카카오 로그인 클래스입니다.

<?php

class KakaoLogin {
	
	private $auth_url;
	private $api_url;
	private $callback_url;
	private $cliend_id;	
	private $state;

    /**
     * 생성자
     *
     * @param string $csrf_token
     */
	public function __construct($csrf_token = "") {
	
		$this->callback_url = "https://callback-url";   // 콜백 URL
		$this->auth_url = "https://kauth.kakao.com";    // 카카오 인증서버
		$this->api_url = "https://kapi.kakao.com";      // 카카오 API 서버
		$this->cliend_id = "REST API KEY";
		$this->state = $csrf_token;
		
	}

    /**
     * 인가코드를 받기 위한 URL 생성
     *
     * @return string
     */
	public function getAuthorizeUrl() {
				
		$returnValue = $this->auth_url."/oauth/authorize?";
		$returnValue .= "client_id={$this->cliend_id}";
		$returnValue .= "&redirect_uri=".urlencode($this->callback_url);
		$returnValue .= "&state={$this->state}";
		$returnValue .= "&response_type=code";  //&prompt=login
		
		return $returnValue;		
	}

    /**
     * 인가코드를 이용해 토큰 요청
     *
     * @param string $code
     * @return array
     */
	public function getToken($code) {
		
        // 토큰 주소
		$url = $this->auth_url . "/oauth/token";
		
        // 헤더
		$headers = array(
			"Content-type: application/x-www-form-urlencoded;charset=utf-8"
		);
		
        // 데이터
		$postData = array(
			"grant_type" => "authorization_code",
			"client_id" => $this->cliend_id,
			"redirect_uri" => $this->callback_url,
			"code" => $code,
			"client_secret" => ""
		);
				
        // API 호출
		$arrResult = $this->call($headers, $url, $postData);

		$returnData = json_decode($arrResult[0], true);

		$retVal["code"] = $arrResult[3];
		$retVal["data"] = $returnData;

		return $retVal;
	}
	
	
	/**
	 * Access Token 을 이용해 사용자 정보 가져오기
	 * @param string $accessToken
	 * @return array
	 */
	public function getUserInfo($accessToken) {
		
		$url = $this->api_url . "/v2/user/me";
		
		$headers = array(
			"Authorization: Bearer {$accessToken}",
			"Content-type: application/x-www-form-urlencoded;charset=utf-8",			
		);
				
		$arrResult = $this->call($headers, $url, $postData);
		
		$returnData = json_decode($arrResult[0], true);
		
		$retVal["code"] = $arrResult[3];
		$retVal["data"] = $returnData;
		
		return $retVal;
	}


    /**
      * 실제 API 호출 메서드
      *
      * @param array $headers
      * @param string $url
      * @param array $postData
      * @return array
      */
	private function call($headers, $url, $postData = null) {

		try {	

			$postDataString = "";
			if(is_array($postData)){
				$postDataString = http_build_query($postData);
			}
			
			$ch = curl_init();
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
			curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
			curl_setopt($ch, CURLOPT_HEADER, false);
			curl_setopt($ch, CURLOPT_POST, true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $postDataString);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

			$result[0] = curl_exec($ch);
			$result[1] = curl_errno($ch);
			$result[2] = curl_error($ch);
			$result[3] = curl_getinfo($ch, CURLINFO_HTTP_CODE);

			
			return $result;
		} catch(Exception $e) {
			echo $e->getMessages();

            return array("false");
		}
	}
}

 

getAuthorizeUrl() 메서드를 이용해서 인가 코드를 받을 수 있는 URL 주소를 생성하고 해당 링크를 이용하면 인가 코드를 받을 수 있습니다.

 

인가 코드를 받는 콜백 페이지 소스 코드입니다.

<?php

include $_SERVER["DOCUMENT_ROOT"] . "/openapi/kakaoLogin/KakaoLogin.php";

// callback 으로 들어온 값을 확인한다.
$code = $_REQUEST["code"];
$state = $_REQUEST["state"];
$error = $_REQUEST["error"];
$error_description = $_REQUEST["error_description"];


if($error) {	
	echo "<script>alert('문제가 발생해서 정상적으로 로그인이 되지 않았습니다. [{$error}]');location.href='/';</script>";
	exit();
}

// 카카오로그인 객체 생성
$kakao = new KakaoLogin($_SESSION['csrf-token']);

// 토큰 받기
$tokenData = $kakao->getToken($code);

// 사용자 정보 가져오기.
if(! empty($tokenData["data"]["access_token"])) {

	$userInfoData = $kakao->getUserInfo($tokenData["data"]["access_token"]);

    // 사용자 정보를 이용해 추가 로직 

}

 

 인가 코드를 받은 후 해당 코드를 사용해 토큰을 받아온 후 사용자의 정보를 이용해 로그인 처리를 진행하면 됩니다.

csrf-token 값을 이용해 state 인자와 비교해 csrf 공격인지 확인할 수 있도록 작업되어 있습니다. (해당 코드는 여기에 없습니다.)

 

카카오 인증 서버와 카카오 API 서버의 주소가 다르기 때문에 잘 분리해서 사용하시면 됩니다. 

728x90
Comments