feat: 更新环境配置并增强 iframe 安全处理机制
修改 .env.example,优化环境切换说明,并新增 API_BASE_URL 配置项,提升配置管理能力。 更新 next.config.ts:使用 API_BASE_URL 代理 API 请求,增强开发与生产环境的灵活性。 重构 iframe-bridge 与 use-token-refresh 组件,采用新的 iframe 来源校验方法,提升安全性检查能力。 优化 csp-config.ts:动态注入允许的父级来源(parent origins)到 CSP 配置中,强化安全策略。 调整 lottery-http:通过 Next.js 代理转发 API 请求,简化 API 调用流程。
This commit is contained in:
@@ -18,10 +18,37 @@ const ALLOWED_PARENT_ORIGINS: string[] = [
|
||||
// 生产环境应从环境变量读取
|
||||
].filter((o): o is string => Boolean(o));
|
||||
|
||||
function normalizeOrigin(value: string): string | null {
|
||||
try {
|
||||
return new URL(value).origin;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function staticAllowedParentOrigins(): string[] {
|
||||
return Array.from(
|
||||
new Set(
|
||||
ALLOWED_PARENT_ORIGINS
|
||||
.map((origin) => normalizeOrigin(origin))
|
||||
.filter((origin): origin is string => origin !== null),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 CSP 指令字符串
|
||||
*/
|
||||
export function generateCSP(): string {
|
||||
export function generateCSP(extraParentOrigins: string[] = []): string {
|
||||
const parentOrigins = Array.from(
|
||||
new Set([
|
||||
...staticAllowedParentOrigins(),
|
||||
...extraParentOrigins
|
||||
.map((origin) => normalizeOrigin(origin))
|
||||
.filter((origin): origin is string => origin !== null),
|
||||
]),
|
||||
);
|
||||
|
||||
const directives: Record<string, string[]> = {
|
||||
// 默认只允许同源
|
||||
"default-src": ["'self'"],
|
||||
@@ -42,7 +69,7 @@ export function generateCSP(): string {
|
||||
"connect-src": [
|
||||
"'self'",
|
||||
process.env.NEXT_PUBLIC_API_URL || "",
|
||||
process.env.NEXT_PUBLIC_LOTTERY_API_BASE_URL || "",
|
||||
process.env.API_BASE_URL || "",
|
||||
// WebSocket 连接
|
||||
"ws:",
|
||||
"wss:",
|
||||
@@ -55,10 +82,10 @@ export function generateCSP(): string {
|
||||
"object-src": ["'none'"],
|
||||
|
||||
// 框架允许同源和指定父站
|
||||
"frame-src": ["'self'", ...ALLOWED_PARENT_ORIGINS],
|
||||
"frame-src": ["'self'", ...parentOrigins],
|
||||
|
||||
// 允许被嵌入到指定父站
|
||||
"frame-ancestors": ["'self'", ...ALLOWED_PARENT_ORIGINS],
|
||||
"frame-ancestors": ["'self'", ...parentOrigins],
|
||||
|
||||
// 表单提交允许同源
|
||||
"form-action": ["'self'"],
|
||||
@@ -88,11 +115,7 @@ export function isAllowedParent(parentOrigin: string): boolean {
|
||||
/**
|
||||
* 安全头配置(用于 next.config.ts)
|
||||
*/
|
||||
export const securityHeaders = [
|
||||
{
|
||||
key: "Content-Security-Policy",
|
||||
value: generateCSP(),
|
||||
},
|
||||
export const nonCspSecurityHeaders = [
|
||||
{
|
||||
key: "X-Content-Type-Options",
|
||||
value: "nosniff",
|
||||
@@ -106,3 +129,11 @@ export const securityHeaders = [
|
||||
value: "camera=(), microphone=(), geolocation=()",
|
||||
},
|
||||
];
|
||||
|
||||
export const securityHeaders = [
|
||||
{
|
||||
key: "Content-Security-Policy",
|
||||
value: generateCSP(),
|
||||
},
|
||||
...nonCspSecurityHeaders,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user