-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNAVER.php
334 lines (299 loc) · 8.67 KB
/
NAVER.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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
<?php
/**
* Project: NAVER :: 네이버 로그인(oauth2) pear package<br>
* File: NAVER.php<br>
* 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/NAVER pear package는
* {@link http://developer.naver.com/wiki/pages/NaverLogin 네이버 아이디로 로그인}
* 을 pear package로 구현을 한 것이다.
*
* {@link http://developer.naver.com/wiki/pages/NaverLogin 네이버 아이디로 로그인}은
* {@link http://developer.naver.com/wiki/pages/OAuth2 네이버 OAuth}와는 다른 API로서
* 로그인 사용자의 개인 식별 정보를 활용할 수 있으며, OAuth2 방식으로 구현이 되어있다.
*
* 이 package를 사용하기 위해서는 먼저 Naver에서 ClientID와 ClientSecret을 발급받아야
* 한다. http://developer.naver.com/wiki/pages/NaverLogin 를 참고하라.
*
* !!참고
* oops/NAVER pear package는 더이상 개발되지 않습니다.
* {@link http://pear.oops.org/docs/li_oops-OAUTH2.html oops/OAUTH2 package}를
* 사용하시기 바랍니다.
*
* @category HTTP
* @package NAVER
* @author JoungKyun.Kim <http://oops.org>
* @copyright (c) 2018, OOPS.org
* @license BSD License
* @link http://pear.oops.org/package/NAVER
* @since File available since release 1.0.0
* @example NAVER/tests/test.php NAVER pear package 예제 코드
* @filesource
*/
/**
* import HTTPRelay class
*/
require_once 'HTTPRelay.php';
/**
* Naver pear pcakge의 main class
*
* OAuth2를 이용하여 네이버 로그인을 진행하고, 로그인된 사용자의
* 정보를 얻어온다.
*
* !!참고
* oops/NAVER pear package는 더이상 개발되지 않습니다.
* {@link http://pear.oops.org/docs/li_oops-OAUTH2.html oops/OAUTH2 package}를
* 사용하시기 바랍니다.
*
* @package NAVER
* @author JoungKyun.Kim <http://oops.org>
* @copyright (c) 2018, OOPS.org
* @license BSD License
* @link http://pear.oops.org/package/NAVER
* @since File available since release 1.0.0
* @example NAVER/tests/test.php NAVER pear 예제 코드
*/
Class NAVER {
// {{{ properities
/**#@+
* @access private
*/
/**
* 세션 이름
* @var string
*/
private $sessid = 'NaverOauth';
/**
* login url
* @var string
*/
private $reqAuth = 'https://nid.naver.com/oauth2.0/authorize';
/**
* token url
* @var string
*/
private $reqToken = 'https://nid.naver.com/oauth2.0/token';
/**
* user information url
* @var string
*/
private $reqUser = 'https://apis.naver.com/nidlogin/nid/getUserProfile.xml';
/**
* consumer information
* @var stdClass memebr는 다음과 같음
* - id : Naver login CliendID key
* - secret : Naver login ClientSecret key
* - callback : 이 class를 호출하는 페이지
*/
private $consumer;
/**#@-*/
/**
* 네이버 로그인에 필요한 session 값
* @access public
* @var stdClass
*/
public $sess;
// }}}
// {{{ +-- public (void) __construct ($v)
/**
* Naver 로그인 인증 과정을 수행한다. 인증 과정 중에
* 에러가 발생하면 myException 으로 에러 메시지를
* 보낸다.
*
* @access public
* @param stdClass $v
* - id 발급받은 Naver login ClientID key
* - secret 발급받은 Naver login ClientScret key
* - callback 이 클래스가 호출되는 url
* @return void
*/
function __construct ($v) {
if ( ! isset ($_SESSION[$this->sessid]) ) {
$_SESSION[$this->sessid] = new stdClass;
$_SESSION[$this->sessid]->appId = (object) $v;
}
$this->sess = &$_SESSION[$this->sessid];
$this->consumer = (object) $v;
if ( isset ($_GET['logout']) ) {
$this->reqLogout ();
return;
}
$this->checkError ();
$this->reqLogin ();
$this->reqAccessToken ();
}
// }}}
// {{{ +-- private (string) mkToken (void)
/**
* 세션 유지를 위한 token 값
*
* @access private
* @return string
*/
private function mkToken () {
$mt = microtime ();
$rand = mt_rand ();
return md5 ($mt . $rand);
}
// }}}
// {{{ +-- private (void) reqLogin (void)
/**
* 로그인 창으로 redirect
*
* @access private
* @return void
*/
private function reqLogin () {
$cons = &$this->consumer;
$this->sess->state = $this->mkToken ();
if ( $_GET['code'] || isset ($this->sess->oauth) )
return;
$url = sprintf (
'%s?client_id=%s&response_type=code&redirect_uri=%s&state=%s',
$this->reqAuth, $cons->id, rawurlencode ($cons->callback),
$this->sess->state
);
Header ('Location: ' . $url);
exit;
}
// }}}
// {{{ +-- private (void) reqAccessToken (void)
/**
* Authorization code를 발급받아 session에 등록
*
* NAVER::$sess->oauth 를 stdClass로 생성하고 다음의
* member를 등록한다.
*
* - access_token: 발급받은 access token. expires_in(초) 이후 만료
* - refresh_token: access token 만료시 재발급 키 (14일 expire)
* - token_type: Bearer or MAC
* - expires_in: access token 유효시간(초)
* - error: error code
* - error_description: error 상세값
*
* @access private
* @return void
*/
private function reqAccessToken () {
$sess = &$this->sess;
$cons = &$this->consumer;
if ( ! $_GET['code'] || isset ($sess->oauth) )
return;
$url = sprintf (
'%s?client_id=%s&client_secret=%s&grant_type=authorization_code&state=%s&code=%s',
$this->reqToken, $cons->id, $cons->secret, $sess->state, $_GET['code']
);
$http = new HTTPRelay;
$buf = $http->fetch ($url);
$r = json_decode ($buf);
if ( $r->error )
$this->error ($r->error_description);
$sess->oauth = (object) $r;
}
// }}}
// {{{ +-- private (void) checkError (void)
/**
* 에러 코드가 존재하면 에러 처리를 한다.
*
* @access private
* @return void
*/
private function checkError () {
$sess = &$this->sess;
if ( $_GET['error'] )
$this->error ($_GET['error_description']);
if ( $_GET['state'] && $_GET['state'] != $sess->state )
$this->error ('Invalude Session state: ' . $_GET['state']);
}
// }}}
// {{{ +-- private (void) error ($msg)
/**
* 에러를 Exception 처리한다.
*
* @access private
* @return void
*/
private function error ($msg) {
$msg = $_SERVER['HTTP_REFERER'] . "\n" . $msg;
throw new myException ($msg, E_USER_ERROR);
}
// }}}
// {{{ +-- public (stdClass) getUser (void)
/**
* 로그인 과정이 완료되면 발급받은 NAVER::$sess->oauth 에 등록된
* 키를 이용하여 로그인 사용자의 정보를 가져온다.
*
* @access public
* @return stdClass 다음의 object를 반환
* - id 사용자 확인 값
* - nickname 사용자 닉네임
* - email 이메일(ID@naver.com)
* - gender 성별 (F:여성/M:남성/U:확인불가)
* - birth 생일 (MM-DD 형식으로 반환)
* - img 프로필 사진 URL 정보
*/
public function getUser () {
$sess = &$this->sess;
if ( ! isset ($sess->oauth) )
return false;
$req = $sess->oauth->token_type . ' ' . $sess->oauth->access_token;
$header = array ('Authorization' => $req);
$http = new HTTPRelay ($header);
$buf = $http->fetch ($this->reqUser);
$xml = simplexml_load_string ($buf);
if ( $xml->result->resultcode != '00' )
$this->error ($r->result->message);
$xmlr = &$xml->response;
$r = array (
'id' => (string) $xmlr->enc_id->{0},
'name' => (string) $xmlr->nickname->{0},
'email' => (string) $xmlr->email->{0},
'gender' => (string) $xmlr->gender->{0},
'age' => (string) $xmlr->age->{0},
'birth' => (string) $xmlr->birthday,
'img' => (string) $xmlr->profile_image
);
return (object) $r;
}
// }}}
// {{{ +-- public (void) reqLogout (void)
/**
* 네이버 로그인의 authorization key를 만료 시키고
* 세션에 등록된 정보(NAVER::$sess)를 제거한다.
*
* @access public
* @return void
*/
public function reqLogout () {
$sess = &$this->sess;
$cons = &$this->consumer;
if ( ! isset ($sess->oauth) )
return;
// guide에는 refresh_token을 넣으라고 되어 있는데,
// 실제로는 access_token을 넣어야 한다.
$url = sprintf (
'%s?grant_type=delete&client_id=%s&client_secret=%s&' .
'access_token=%s&service_provider=NAVER',
$this->reqToken, $cons->id, $cons->secret, $sess->oauth->access_token
);
$http = new HTTPRelay;
$buf = $http->fetch ($url);
$r = json_decode ($buf);
if ( $r->error )
$this->error ($r->error_description);
unset ($_SESSION[$this->sessid]);
}
// }}}
}
/*
* 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
*/
?>