feat: OIDC 로그인 연동 및 DB 스키마 업데이트

This commit is contained in:
2026-02-02 09:50:25 +09:00
parent 21b6332c9c
commit a976b8a0c6
30 changed files with 2029 additions and 5 deletions

View 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>";
}