- 引入 openid-client,新增 /api/auth/oidc/login + /api/auth/oidc/callback - 通过 email 绑定既有员工账号,保留密码登录 fallback - OIDC 状态存 cookie(HMAC) + PKCE + SameSite=lax 防 CSRF - 更新 env/README 与 v3 CSV 状态推进
65 行
1.5 KiB
JavaScript
65 行
1.5 KiB
JavaScript
const { Issuer, generators } = require("openid-client");
|
|
|
|
function validateOidcConfig(config) {
|
|
if (!config?.oidcEnabled) {
|
|
throw new Error("OIDC is disabled");
|
|
}
|
|
|
|
if (!config.oidcIssuerUrl) {
|
|
throw new Error("Missing OIDC_ISSUER_URL");
|
|
}
|
|
|
|
if (!config.oidcClientId) {
|
|
throw new Error("Missing OIDC_CLIENT_ID");
|
|
}
|
|
|
|
if (!config.oidcRedirectUri) {
|
|
throw new Error("Missing OIDC_REDIRECT_URI");
|
|
}
|
|
|
|
return {
|
|
issuerUrl: config.oidcIssuerUrl,
|
|
clientId: config.oidcClientId,
|
|
clientSecret: config.oidcClientSecret || undefined,
|
|
redirectUri: config.oidcRedirectUri,
|
|
scopes: config.oidcScopes || "openid profile email",
|
|
};
|
|
}
|
|
|
|
let cachedClientPromise = null;
|
|
let cachedClientKey = null;
|
|
|
|
async function getOidcClient(config) {
|
|
const oidc = validateOidcConfig(config);
|
|
const key = JSON.stringify({
|
|
issuerUrl: oidc.issuerUrl,
|
|
clientId: oidc.clientId,
|
|
redirectUri: oidc.redirectUri,
|
|
});
|
|
|
|
if (cachedClientPromise && cachedClientKey === key) {
|
|
return cachedClientPromise;
|
|
}
|
|
|
|
cachedClientKey = key;
|
|
cachedClientPromise = Issuer.discover(oidc.issuerUrl).then((issuer) => {
|
|
const client = new issuer.Client({
|
|
client_id: oidc.clientId,
|
|
client_secret: oidc.clientSecret,
|
|
redirect_uris: [oidc.redirectUri],
|
|
response_types: ["code"],
|
|
});
|
|
|
|
return { issuer, client, config: oidc };
|
|
});
|
|
|
|
return cachedClientPromise;
|
|
}
|
|
|
|
module.exports = {
|
|
generators,
|
|
getOidcClient,
|
|
validateOidcConfig,
|
|
};
|
|
|