-
Notifications
You must be signed in to change notification settings - Fork 2
/
OAUTH2.php
231 lines (206 loc) · 6.39 KB
/
OAUTH2.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
<?php
/**
* Project: oops\OAUTH2:: OAUTH2 pear package<br>
* File: OAUTH2.php<br>
* Dependency:
* - {@link http:https://pear.oops.org/docs/li_HTTPRelay.html oops/HTTPRelay}
* - {@link http:https://pear.oops.org/docs/li_myException.html oops/myException}
* - {@link http:https://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 <http:https://oops.org>
* @copyright (c) 2020, OOPS.org
* @license BSD License
* @link http:https://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 <http:https://oops.org>
* @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
*/