* File: OAUTH2.php
* Dependency:
* - {@link http://pear.oops.org/docs/li_HTTPRelay.html oops/HTTPRelay}
* - {@link http://pear.oops.org/docs/li_myException.html oops/myException}
* - {@link http://kr1.php.net/manual/en/book.curl.php curl extension}
*
* oops\OAUTH2 pear package는 OAUTH2 login 및 profile 정보를
* 다루기 위한 library이다.
*
* 이 package를 사용하기 위해서는 먼저 각 모듈의 벤더 페이지에서
* Application ID와 Application Secret을 발급받아야 한다. 각 모듈의
* 상단 주석을 참조하라.
*
* 현재 GOOGLE, FACEBOOK, NAVER, GITHUB, KAKAO 를 지원한다.
*
* @category HTTP
* @package oops\OAUTH2
* @author JoungKyun.Kim
* @copyright (c) 2020, OOPS.org
* @license BSD License
* @link http://pear.oops.org/package/OAUTH2
* @example OAUTH2/tests/test.php OAUTH2 pear package 예제 코드
* @filesource
*/
/**
* Namespace oops;
*/
namespace oops;
/**
* import myException class
*/
require_once 'myException.php';
/**
* oops\OAUth2 pear package의 main class
*
* OAUTH2를 이용하여 로그인을 진행하고, 로그인된 사용자의
* 프로필 정보를 관리한다.
*
* 현재 GOOGLE, FACEBOOK, NAVER, GITHUB, KAKAO 를 지원한다.
*
* @package oops/OAUTH2
* @author JoungKyun.Kim
* @copyright (c) 2020, OOPS.org
* @license BSD License
* @example OAUTH2/tests/test.php OAUTH2 pear 예제 코드
*/
Class OAUth2 {
// {{{ properities
/**
* @access public
* @var stdClass 벤더 정고
*/
public $vendor;
/**
* access private
* @var object
*/
private $o;
// }}}
// {{{ +-- public (void) __construct ($app)
/**
* OAUTH2 로그인 인증 과정을 수행한다. 인증 과정 중에 에러가
* 발생하면 myException으로 에러 메시지를 보낸다.
*
* logout 시에 globale 변수 $_OAUTH2_LOGOUT_TEMPALTE_ 로 사용자 logout template
* 을 지정할 수 있다. template 파일은 pear/OAUTH2/login.template 를 참조하면 된다.
*
* @access public
* @param stdClass $app 로그인 정보
* - vendor OAUTH2 Service Provider (현재 google/facebook/naver/kakao 지원)
* - id Service Provider 에서 발급받은 client ID
* - secret Service Provider 에서 발급받은 client secret key
* - callback 이 class가 호출되는 URL (또는 provider에 등록한 callback url)
* - popup Facebook 처럼 popup login 창을 지원하는 경우 ture 로 지정
* @return void
*/
function __construct ($app) {
$this->vendor = strtoupper ($app->vendor);
$resource = sprintf ('OAUTH2/%s.php', $this->vendor);
if ( ! $this->file_exists ($resource) )
throw new \myException (sprintf ('Unsupport vendor "%s"', $app->vendor));
require_once $resource;
$className = sprintf ('oops\OAUTH2\%s', $this->vendor);
$this->o = new $className ($app);
}
// }}}
// {{{ +-- public Profile (void)
/**
* 로그인이 성공 후에, 로그인 사용자의 Profile을 가져오기 위한
* API
*
* @access public
* @return stdClass 사용자 Profile
* - id 사용자 UID
* - name 사용자 Nickname
* - email 사용자 email (Provider에 따라 없을 수도 있다.)
* - img 사용자 profile image url
* - r 각 provider에서 제공하는 original profile 값
*/
public function Profile () {
return $this->o->Profile ();
}
// }}}
// {{{ +-- static public (stdClass) image ($url, $noprint = false)
/**
* 외부 이미지를 읽어와서 출력한다. HTTPS protocold을 사용할
* 경우 provider에서 https image를 지원하지 않을 경우 사용.
*
* @access public
* @param string $url 원본 image URL
* @param bool $noprint (optional) true로 설정하면 출력하지
* 않고 반환한다. (default: false)
* @return stdClass 2번째 인자가 true일 경우에는 void 이다.
* - type gif/jpg/png 중 하나
* - data image raw data
*/
static public function image ($url, $noprint = false) {
if ( ! $url )
return;
if ( preg_match ('!^//!', $url) ) {
if ( $_SERVER['HTTPS'] )
$url = 'https:' . $url;
else
$url = 'http:' . $url;
}
if ( ! ($url = filter_var($url, FILTER_VALIDATE_URL)) )
return;
$c = curl_init ();
curl_setopt ($c, CURLOPT_URL, $url);
curl_setopt ($c, CURLOPT_TIMEOUT, 60);
curl_setopt ($c, CURLOPT_NOPROGRESS, 1);
curl_setopt ($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($c, CURLOPT_USERAGENT, "OAUTH2 pear package");
curl_setopt ($c, CURLOPT_HEADER, 0);
curl_setopt ($c, CURLOPT_NOBODY, 0);
curl_setopt ($c, CURLOPT_FAILONERROR, 1);
$data = curl_exec($c);
$info = (object) curl_getinfo ($c);
if ( $info->http_code == 302 )
return self::image ($info->redirect_url, $noprint);
$ctype = $info->content_type;
if ( ! $noprint ) {
Header ('Content-Type: ' . $ctype);
echo $data;
}
curl_close ($c);
if ( $noprint ) {
preg_match ('!/([a-z]+)!', $ctype, $matches);
if ( $matches[1] == 'jpeg' )
$matches[1] = 'jpg';
return (object) array (
'type' => $matches[1],
'data' => $data
);
}
}
// }}}
// {{{ +-- private (mixed) ini_get ($var)
/**
* Gets the value of a configuration option
*
* @access private
* @param string $var ini option 이름
* @return mixed Returns the value of the configuration option as
* a string on success, or an empty string for null values.
* Returns FALSE if the configuration option doesn't exist.
*/
private function ini_get ($var) {
$func = function_exists ('___ini_get') ? '___' : '';
$func .= 'ini_get';
return $func ($var);
}
// }}}
// {{{ +-- private (bool) file_exists ($f)
/**
* 파일이나 디렉토리가 존재하는지 여부를 판단한다. pure file_exists
* 와의 차이는 include_path를 지원한다.
*
* @access private
* @param string $f 파일 경로
* @return bool 지정한 파일이나 디렉토리가 있으면 true를 반환하고
* 없으면 false를 반환
*/
private function file_exists ($f) {
if ( @file_exists ($f) )
return true;
$entry = preg_split ('/:/', $this->ini_get ('include_path'));
foreach ($entry as $base) {
if ( @file_exists ($base . '/' . $f) )
return true;
}
return false;
}
// }}}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/