[php] 네이버 로그인 연동 api class 구현 프로그래밍

1. https://developers.naver.com/

접속해서 애플리케이션 생성

로그인 client_id 와 client_secret 생성하기.

리다이렉트 url 설정하기.

 

2. class 구현

function fnRequestCurl( $url, $is_post = 0, $data = [], $custom_header = null ) {
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
    curl_setopt( $ch, CURLOPT_SSLVERSION, 1 );
    curl_setopt( $ch, CURLOPT_POST, $is_post );
    if( $is_post ) {
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $data );
    }

    curl_setopt( $ch, CURLOPT_TIMEOUT, 300 );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
    //curl_setopt ($ch, CURLOPT_HEADER, true);

    if( $custom_header ) {
        curl_setopt( $ch, CURLOPT_HTTPHEADER, $custom_header );
    }
    $result[0] = curl_exec( $ch );
    $result[1] = curl_errno( $ch );
    $result[2] = curl_error( $ch );
    $result[3] = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
    curl_close( $ch );
    return $result;
}


class OAuthNaverRequest {

    const CLIENT_ID = '클라이언트 id';
    const CLIENT_SECRET = '클라이언트 시크릿 key';
    const REDIRECT_URL = '리다이렉트 url';
    const AUTHORIZE_URL = 'https://nid.naver.com/oauth2.0/authorize';
    const ACCESSTOKEN_URL = 'https://nid.naver.com/oauth2.0/token';
    const USERINFO_URL = 'https://openapi.naver.com/v1/nid/me';

    private $state;
    private $code;
    private $tokenArr;

    function __construct() {
        if(!isset($_SESSION)) {
            session_start();
        }
    }

    function __destruct() {
        //unset($_SESSION['naver_state']);
    }

    private function fnGenerateState() {
        $mt = microtime();
        $rand = mt_rand();
        $this->state = md5( $mt . $rand );
    }

    public function fnSetState() {
        $this->fnGenerateState();
        $_SESSION['naver_state'] = $this->state;
    }

    private function fnGetCode() {
        $this->code = $_GET['code'];
    }

    private function fnGetState() {
        $this->state = $_SESSION['naver_state'];
        return $this->state;
    }

    public function fnRequestAuth() {
        header('Location: '. $this->fnGetLoginUrl() );
    }

    public function fnGetLoginUrl() {
        $this->fnSetState();
        return self::AUTHORIZE_URL . '?response_type=code&client_id=' . self::CLIENT_ID . '&state=' . $this->state . '&redirect_url=' . urlencode(self::REDIRECT_URL);
    }

    public function fnGetAccessTokenUrl() {
        return self::ACCESSTOKEN_URL . '?grant_type=authorization_code&client_id=' . self::CLIENT_ID . '&client_secret=' . self::CLIENT_SECRET . '&code=' . $this->code . '&state= ' . $this->state;
    }

    /**
     * 유저정보를 조회하기전 access토큰을 발급할때..
     *
     * @return bool 성공/실패
     */
    public function fnCallAccessToken() {
        $this->fnGetCode();
        $this->fnGetState();

        $result = fnRequestCurl($this->fnGetAccessTokenUrl(), 0, [], null );

        //print_r($result);

        if( $result[3] != 200 ) {
            echo 'AccessToken 발급 실패.';
            return false;
        }

        $data = json_decode($result[0]);
        $this->tokenArr = [
            "Authorization: Bearer ".$data->access_token
        ];

        return true;

    }

    /**
     * 토큰 발행후 유저정보를 조회할떄..
     * 
     * @return bool|mixed
     */
    public function fnGetUserProfile() {

        if( empty($this->tokenArr) ) {
            echo 'fnCallAccessToken 부터 호출해서 AccessToken을 받아야 합니다.';
            return false;
        }

        $result = fnRequestCurl(self::USERINFO_URL, 0, [], $this->tokenArr);

        //print_r($result);

        if( $result[3] != 200 ) {
            echo 'UserProfile 호출에 실패하였습니다!';
            return false;
        }

        $data = json_decode($result[0]);

        return $data;

    }

}

 

 

3. 로그인버튼 구현부

<?php
    $request = new OAuthNaverRequest();
?>
<a href="<?=$request->fnGetLoginUrl()?>"><img src="naver_login.jpg" alt="네이버 로그인"></a>

 

3. 버튼 누른후 action (리다이렉트 url 부분)

// naver obj 생성
$request = new OAuthNaverRequest();
// 토근 생성
$result = $request->fnCallAccessToken();
// 토근 생성에 실패하면
if( !$result ) {
    alert('로그인에 통신에 하였습니다. 관리자에게 문의해주세요.',$referer);
    return false;
}
// 토큰으로 유저정보 받기
$strArrNaverUser = $request->fnGetUserProfile();

if( !$strArrNaverUser || $strArrNaverUser->message != 'success' ) {
    alert('유저정보 조회에 실패하였습니다. 관리자에게 문의해주세요.',$referer);
    return false;
}

$flag   = fnGetMember($strArrNaverUser->response->email);

if( $flag === false ) {
    echo '가입된 멤버가 없습니다!';
    // Todo.. 
    // 회원가입페이지로 이동
} else {
    echo '가입된 멤버가 있습니다.';
    // Todo.. 
    // 로그인처리
}

 

구글에서 검색후 어떤 분이 포스팅한 class를 가져와서 최신에 맞게 커스터마이징 하였다.

이전분이 구현한 class는 2014~2015년도 것 이여서 조금 바뀐부분만 수정.

출처 - http://blog.publisher.name/499

Tag :

Leave Comments