feat: OIDC 로그인 연동 및 DB 스키마 업데이트
This commit is contained in:
89
kngil/auth/oidc-callback.php
Normal file
89
kngil/auth/oidc-callback.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
// /kngil/auth/oidc-callback.php
|
||||
session_start();
|
||||
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||
require_once dirname(__DIR__) . '/bbs/db_conn.php';
|
||||
$config = require_once dirname(__DIR__) . '/bbs/oidc_config.php';
|
||||
|
||||
use Jumbojett\OpenIDConnectClient;
|
||||
|
||||
$oidc = new OpenIDConnectClient(
|
||||
$config['issuer'],
|
||||
$config['client_id'],
|
||||
$config['client_secret']
|
||||
);
|
||||
|
||||
$oidc->setRedirectURL($config['redirect_url']);
|
||||
|
||||
try {
|
||||
if (!$oidc->authenticate()) {
|
||||
throw new Exception("Authentication failed");
|
||||
}
|
||||
|
||||
$userInfo = $oidc->requestUserInfo();
|
||||
// $userInfo 에 포함된 데이터 예시: sub, email, name, preferred_username 등
|
||||
|
||||
$email = $userInfo->email ?? null;
|
||||
$sub = $userInfo->sub ?? null; // IDP 고유 식별자
|
||||
$name = $userInfo->name ?? ($userInfo->preferred_username ?? 'Unknown');
|
||||
|
||||
if (!$email && !$sub) {
|
||||
throw new Exception("IDP provided insufficient user information.");
|
||||
}
|
||||
|
||||
// 1. 사용자 매핑 (sub 또는 email 기준)
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT * FROM kngil.users
|
||||
WHERE (oidc_sub = :sub OR LOWER(email) = LOWER(:email))
|
||||
AND use_yn = 'Y'
|
||||
LIMIT 1
|
||||
");
|
||||
$stmt->execute([':sub' => $sub, ':email' => $email]);
|
||||
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$user) {
|
||||
// [정책 선택] 새 사용자 자동 생성 또는 로그인 거부
|
||||
// 여기서는 예시로 로그인 거부 처리
|
||||
throw new Exception("등록되지 않은 사용자입니다. 관리자에게 문의하세요. (IDP: $email)");
|
||||
}
|
||||
|
||||
// 2. oidc_sub 업데이트 (최초 연동 시)
|
||||
if (empty($user['oidc_sub']) && $sub) {
|
||||
$upd = $pdo->prepare("UPDATE kngil.users SET oidc_sub = :sub WHERE user_id = :id");
|
||||
$upd->execute([':sub' => $sub, ':id' => $user['user_id']]);
|
||||
}
|
||||
|
||||
// 3. 세션 설정 (bbs/login.php 와 동일한 구조)
|
||||
$_SESSION['login'] = [
|
||||
'member_id' => $user['member_id'],
|
||||
'user_id' => $user['user_id'],
|
||||
'user_nm' => $user['user_nm'],
|
||||
'auth_bc' => $user['auth_bc'],
|
||||
'co_nm' => $user['co_nm'] ?? null,
|
||||
'dept_nm' => $user['dept_nm'] ?? null,
|
||||
'tel_no' => $user['tel_no'] ?? null,
|
||||
'email' => $user['email'] ?? null,
|
||||
'oidc_mode' => true // OIDC 로그인을 나타내는 플래그
|
||||
];
|
||||
|
||||
// 로그인 완료 후 부모 창에 알리고 종료
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
if (window.opener) {
|
||||
window.opener.postMessage({ type: 'OIDC_LOGIN_SUCCESS' }, window.location.origin);
|
||||
}
|
||||
window.close();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
exit;
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "<h1>로그인 오류</h1>";
|
||||
echo "<p>" . htmlspecialchars($e->getMessage()) . "</p>";
|
||||
echo "<a href='/kngil/index.php'>메인으로 돌아가기</a>";
|
||||
}
|
||||
Reference in New Issue
Block a user