미인증 진입 시 중간 화면 없이 곧장 Keycloak 로그인 폼으로 리다이렉트
- requireAuth: /login 거치지 않고 loginRedirect로 직접 Keycloak으로 - /login 라우트도 oidcReady면 즉시 리다이렉트 - OIDC discovery 실패 시에만 안내 페이지 폴백, /api/*는 401 유지 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
12
src/auth.js
12
src/auth.js
@@ -4,6 +4,11 @@ import { config } from "./config.js";
|
||||
|
||||
let client;
|
||||
|
||||
// OIDC 클라이언트가 준비됐는지(discovery 성공) 여부
|
||||
export function oidcReady() {
|
||||
return !!client;
|
||||
}
|
||||
|
||||
export async function initOidc() {
|
||||
const issuer = await Issuer.discover(config.oidc.issuer);
|
||||
client = new issuer.Client({
|
||||
@@ -47,7 +52,10 @@ export async function handleCallback(req) {
|
||||
// 로그인 필수 가드
|
||||
export function requireAuth(req, res, next) {
|
||||
if (req.session.user) return next();
|
||||
// API 요청은 401, 페이지 요청은 로그인으로
|
||||
// API 요청은 401
|
||||
if (req.path.startsWith("/api/")) return res.status(401).json({ error: "unauthorized" });
|
||||
return res.redirect("/login");
|
||||
// 페이지 요청은 중간 화면 없이 곧장 Keycloak 로그인 폼으로 보낸다.
|
||||
if (oidcReady()) return loginRedirect(req, res);
|
||||
// OIDC 미준비(discovery 실패)면 안내 페이지로 폴백
|
||||
return res.redirect("/login?error=" + encodeURIComponent("로그인 서비스를 사용할 수 없습니다. 잠시 후 다시 시도해 주세요."));
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { fileURLToPath } from "url";
|
||||
import path from "path";
|
||||
import { config } from "./config.js";
|
||||
import { siteGroups } from "./sites.js";
|
||||
import { initOidc, loginRedirect, handleCallback, requireAuth } from "./auth.js";
|
||||
import { initOidc, loginRedirect, handleCallback, requireAuth, oidcReady } from "./auth.js";
|
||||
import * as db from "./db.js";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
@@ -36,9 +36,14 @@ app.use((req, res, next) => {
|
||||
app.get("/healthz", (_req, res) => res.json({ ok: true }));
|
||||
|
||||
// --- 인증 ---
|
||||
// SSO 세션이 없으면 중간 페이지 없이 바로 Keycloak(커스텀 테마) 로그인으로 보낸다.
|
||||
// (OIDC 초기화 실패 등으로 로그인 불가하면 안내용 login.ejs 로 폴백)
|
||||
app.get("/login", (req, res) => {
|
||||
if (req.session.user) return res.redirect("/");
|
||||
res.render("login");
|
||||
if (req.query.error) return res.render("login", { error: req.query.error });
|
||||
// OIDC 준비됐으면 중간 화면 없이 곧장 Keycloak 로그인 폼으로
|
||||
if (oidcReady()) return loginRedirect(req, res);
|
||||
return res.render("login", { error: "로그인 서비스를 사용할 수 없습니다. 잠시 후 다시 시도해 주세요." });
|
||||
});
|
||||
app.get("/auth/login", (req, res) => loginRedirect(req, res));
|
||||
app.get("/auth/callback", async (req, res) => {
|
||||
|
||||
Reference in New Issue
Block a user