- /modules/oauth/Oauth.php
-
93
*
-
94
* @param string $oauth_id 제공자고유값
-
95
* @param string $redirect 인증을 마친 뒤 돌아갈 주소
-
96
* @return Models\Authorization $authorization
-
97
*/
-
98
public function createAuthorization(string $oauth_id, string $redirect): Models\Authorization
-
99
{ -
100
Session::start('READ'); -
101
$session_id = session_id();
- 102
-
103
$authorization = [
-
104
'uuid' => UUID::v4(),
-
105
'oauth_id' => $oauth_id,
-
106
'member_id' => Members::getMemberId(),
-
107
'session_id' => $session_id === false || $session_id === '' ? null : Password::encode($session_id),
-
108
'redirect' => $redirect,
-
109
'created_at' => time(),
-
110
'authorized_at' => 0,
-
111
];
-
112
$this->db()->insert($this->table('authorizations'), $authorization)->execute(); - 113
-
114
Response::cookie('IM_OAUTH_STATE', Password::encode($authorization['uuid']), 3600); - 115
-
116
return new Models\Authorization((object) $authorization);
-
117
}
- 118
-
119
/**
-
120
* OAuth 인증진행정보를 가져온다.
-
121
* 인증을 시작한 브라우저의 쿠키와 고유값이 일치하고, 만료되지 않은 경우에만 가져온다.
-
122
*
-
123
* @param ?string $uuid 인증고유값 (state 파라메터)
-
124
* @return ?Models\Authorization $authorization
-
125
*/
-
126
public function getAuthorization(?string $uuid): ?Models\Authorization
-
127
{ -
128
if ($uuid === null || $uuid === '') { -
129
return null;
-
130
}
- 131
-
132
$cookie = Request::cookie('IM_OAUTH_STATE'); -
133
$cookie = $cookie === null ? false : Password::decode($cookie);
- /modules/oauth/handlers/Auth.php
-
102
$me = $this->getPackage();
- 103
-
104
$referer = $_SERVER['HTTP_REFERER'] ?? null;
-
105
$returnTo = '/';
- 106
-
107
if (is_string($referer)) { -
108
$p = parse_url($referer);
- 109
-
110
$refHost = $p['host'] ?? null;
-
111
$srvHost = $_SERVER['SERVER_NAME'] ?? null;
-
112
$sameHost = $refHost && $srvHost && strcasecmp($refHost, $srvHost) === 0;
- 113
-
114
if ($sameHost) { -
115
$path = $p['path'] ?? '/';
-
116
$query = $p['query'] ?? '';
-
117
$returnTo = $query !== '' ? $path . '?' . $query : $path;
-
118
}
-
119
}
- 120
-
121
$authorization = $me->createAuthorization($client->getId(), $returnTo);
-
122
Response::location($authorization->getAuthUrl());
-
123
}
- 124
-
125
/**
-
126
* OAuth 제공자로부터 전달받은 인증코드로 토큰을 발급받아 인증진행정보에 저장한다.
-
127
* 저장후에는 인증고유값으로 다시 GET 요청하도록 이동하여, 새로고침시 인증코드가 다시 전송되지 않도록 한다.
-
128
*
-
129
* @param Client $client OAuth 클라이언트
-
130
* @param ?string $state 인증고유값
-
131
* @param ?string $code 인증코드
-
132
* @param ?string $error 인증오류
-
133
* @param ?string $user 최초 1회에 한하여 별도로 전달되는 유저정보 (Apple 등)
-
134
*/
-
135
private function getToken(Client $client, ?string $state, ?string $code, ?string $error, ?string $user = null): void
-
136
{ -
137
/**
-
138
* @var \iModules\Modules\Oauth\Oauth
-
139
*/
-
140
$me = $this->getPackage();
- 141
-
142
$authorization = $me->getAuthorization($state);
- /modules/oauth/handlers/Auth.php
-
29
$me = $this->getPackage();
- 30
-
31
Response::type('html'); - 32
-
33
$client = $this->getClient();
- 34
-
35
if (Request::get('code') !== null || Request::get('error') !== null) { -
36
$this->getToken($client, Request::get('state'), Request::get('code'), Request::get('error')); -
37
}
- 38
-
39
if (Request::get('state') !== null) { -
40
$authorization = $me->getAuthorization(Request::get('state')); -
41
if ($authorization === null || $authorization->isAuthorized() == false) { -
42
throw Exceptions::code('OAUTH_INVALID_AUTHORIZATION'); -
43
}
- 44
-
45
$me->loginByOAuth($authorization);
-
46
}
- 47
-
48
$this->authorize($client);
-
49
}
- 50
-
51
/**
-
52
* 인증결과를 POST(form_post) 로 전달받는다. (Apple 등)
-
53
*/
-
54
public function post(): void
-
55
{ -
56
Response::type('html'); - 57
-
58
$this->getToken(
-
59
$this->getClient(),
-
60
Request::post('state'), -
61
Request::post('code'), -
62
Request::post('error'), -
63
Request::post('user'), -
64
);
-
65
}
- 66
-
67
/**
-
68
* 경로에 해당하는 OAuth 클라이언트를 가져온다.
-
69
*
- /app/core/Modules.php
-
357
* 사이트맵을 거치지 않은 모듈 컨텍스트 경로이므로, 컨텍스트 설정의 기본값으로 현재 컨텍스트를 생성한다.
-
358
*/
-
359
$module = Modules::get($name);
- 360
-
361
$method = Request::method();
-
362
$class = new $className($type, $action, $method, $params);
-
363
$handler = $class->getHandler(strtolower($method));
- 364
-
365
if ($handler === null) { -
366
throw Exceptions::code('NOT_FOUND_URL'); -
367
}
- 368
-
369
/**
-
370
* 이벤트를 발생시킨다.
-
371
*/
-
372
if (Events::fireEvent(\iModules\Events\Handler::class, 'beforeHandler', $module, $class) === false) { -
373
// @todo 실행중단
-
374
}
- 375
-
376
$response = call_user_func($handler, $route);
-
377
$response->runtime ??= Application::getTime(Format::microtime());
-
378
$response->updated_at ??= time();
- 379
-
380
/**
-
381
* 이벤트를 발생시킨다.
-
382
*/
-
383
if (Events::fireEvent(\iModules\Events\Handler::class, 'afterHandler', $module, $class, $response) === false) { -
384
// @todo 실행중단
-
385
}
- 386
-
387
Response::code(200);
-
388
exit(Format::toJson($response));
-
389
}
-
390
}
- 391
- /app/models/Route.php
-
323
*/
-
324
public function unmatched(): void
-
325
{ -
326
$this->setLanguage(null);
-
327
$this->_base = null;
-
328
$this->_params = [];
-
329
$this->_values = [];
-
330
$this->_wildcards = [];
-
331
}
- 332
-
333
/**
-
334
* 요청경로에 대한 응답을 처리한다.
-
335
*/
-
336
public function respond(): void
-
337
{ -
338
if ($this->_base === null) { -
339
throw Exceptions::code('MISMATCHED_ROUTE'); -
340
}
- 341
-
342
$result = call_user_func($this->_closure, $this, ...$this->_params, ...$this->_wildcards);
-
343
if ($result === true) { -
344
exit();
-
345
}
-
346
}
-
347
}
- 348
- /app/core/Application.php
-
383
public static function respond(): void
-
384
{ -
385
/**
-
386
* 어플리케이션을 초기화한다.
-
387
*/
-
388
self::init();
- 389
-
390
/**
-
391
* 아이모듈코어 응답에 대한 커스터마이즈가 있다면 적용한다.
-
392
*/
-
393
if (is_file(Config::path() . '/bootstrap/custom.php') == true) { -
394
require_once Config::path() . '/bootstrap/custom.php';
-
395
}
- 396
-
397
/**
-
398
* 요청주소에 해당하는 라우터가 존재할 경우, 해당 라우터를 호출한다.
-
399
*/
-
400
$route = Router::match(Request::route());
-
401
if ($route !== null) { -
402
$route->respond();
-
403
exit();
-
404
}
- 405
-
406
/**
-
407
* 요청주소에 해당하는 경로가 존재하지 않고, 요청 목적지가 document 가 아닐경우 404 에러메시지를 출력한다.
-
408
*/
-
409
if (Request::dest() !== 'document') { -
410
throw Exceptions::http(404);
-
411
}
- 412
-
413
Response::cache();
- 414
-
415
/**
-
416
* 컨텍스트를 초기화한다.
-
417
*/
-
418
Domains::init(Config::debug());
-
419
Sites::init(Config::debug());
-
420
Contexts::init(Config::debug());
- 421
-
422
/**
-
423
* 올바른 주소로 접속하지 않은 경우, 올바른 주소로 이동한다.
- /index.php
-
1
<?php
-
2
/**
-
3
* 이 파일은 아이모듈의 일부입니다. (https://www.imodules.io)
-
4
*
-
5
* 사이트 최초 접속시 실행되는 파일로 기본설정을 불러오고 아이모듈 코어 클래스를 선언하여 요청된 페이지를 반환한다.
-
6
*
-
7
* @file /index.php
-
8
* @author Arzz <arzz@arzz.com>
-
9
* @license MIT License
-
10
* @modified 2026. 7. 28.
-
11
*/
-
12
error_reporting(E_ALL);
-
13
ini_set('display_errors', true); - 14
-
15
require_once __DIR__ . '/bootstrap/app.php';
- 16
-
17
if (PHP_SAPI == 'cli') { -
18
iModules\Core\Cron::execute();
-
19
} else { -
20
iModules\Core\Application::respond();
-
21
}
- 22