feat(安全): 强化安全策略与配置校验

- 增加 CORS/CSP/安全响应头与代理信任配置

- 引入 URL 白名单与私网开关,校验上游与价格源

- 改善 API Key 处理与网关错误返回

- 管理端设置隐藏敏感字段并优化前端提示

- 增加计费熔断与相关配置示例

测试: go test ./...
This commit is contained in:
yangjianbo
2026-01-02 17:40:57 +08:00
parent 3fd9bd4a80
commit bd4bf00856
46 changed files with 1572 additions and 220 deletions

View File

@@ -194,6 +194,7 @@ export default {
registrationFailed: '注册失败,请重试。',
loginSuccess: '登录成功!欢迎回来。',
accountCreatedSuccess: '账户创建成功!欢迎使用 {siteName}。',
reloginRequired: '会话已过期,请重新登录。',
turnstileExpired: '验证已过期,请重试',
turnstileFailed: '验证失败,请重试',
completeVerification: '请完成验证',
@@ -1137,13 +1138,13 @@ export default {
'每行一个 sessionKey例如\nsk-ant-sid01-xxxxx...\nsk-ant-sid01-yyyyy...',
sessionKeyPlaceholderSingle: 'sk-ant-sid01-xxxxx...',
howToGetSessionKey: '如何获取 sessionKey',
step1: '在浏览器中登录 <strong>claude.ai</strong>',
step2: '按 <kbd>F12</kbd> 打开开发者工具',
step3: '切换到 <strong>Application</strong> 标签',
step4: '找到 <strong>Cookies</strong> → <strong>https://claude.ai</strong>',
step5: '找到 <strong>sessionKey</strong> 所在行',
step6: '复制 <strong>Value</strong> 列的值',
sessionKeyFormat: 'sessionKey 通常以 <code>sk-ant-sid01-</code> 开头',
step1: '在浏览器中登录 claude.ai',
step2: '按 F12 打开开发者工具',
step3: '切换到 Application 标签',
step4: '找到 Cookies → https://claude.ai',
step5: '找到 sessionKey 所在行',
step6: '复制 Value 列的值',
sessionKeyFormat: 'sessionKey 通常以 sk-ant-sid01- 开头',
startAutoAuth: '开始自动授权',
authorizing: '授权中...',
followSteps: '按照以下步骤授权您的 Claude 账号:',
@@ -1154,9 +1155,9 @@ export default {
step2OpenUrl: '在浏览器中打开 URL 并完成授权',
openUrlDesc: '在新标签页中打开授权 URL登录您的 Claude 账号并授权。',
proxyWarning:
'<strong>注意:</strong>如果您配置了代理,请确保浏览器使用相同的代理访问授权页面。',
'注意:如果您配置了代理,请确保浏览器使用相同的代理访问授权页面。',
step3EnterCode: '输入授权码',
authCodeDesc: '授权完成后,页面会显示一个 <strong>授权码</strong>。复制并粘贴到下方:',
authCodeDesc: '授权完成后,页面会显示一个授权码。复制并粘贴到下方:',
authCode: '授权码',
authCodePlaceholder: '粘贴 Claude 页面的授权码...',
authCodeHint: '粘贴从 Claude 页面复制的授权码',
@@ -1176,10 +1177,10 @@ export default {
step2OpenUrl: '在浏览器中打开链接并完成授权',
openUrlDesc: '请在新标签页中打开授权链接,登录您的 OpenAI 账户并授权。',
importantNotice:
'<strong>重要提示:</strong>授权后页面可能会加载较长时间,请耐心等待。当浏览器地址栏变为 <code>http://localhost...</code> 开头时,表示授权已完成。',
'重要提示:授权后页面可能会加载较长时间,请耐心等待。当浏览器地址栏变为 http://localhost... 开头时,表示授权已完成。',
step3EnterCode: '输入授权链接或 Code',
authCodeDesc:
'授权完成后,当页面地址变为 <code>http://localhost:xxx/auth/callback?code=...</code> 时:',
'授权完成后,当页面地址变为 http://localhost:xxx/auth/callback?code=... 时:',
authCode: '授权链接或 Code',
authCodePlaceholder:
'方式1复制完整的链接\n(http://localhost:xxx/auth/callback?code=...)\n方式2仅复制 code 参数的值',
@@ -1198,7 +1199,7 @@ export default {
step2OpenUrl: '在浏览器中打开链接并完成授权',
openUrlDesc: '请在新标签页中打开授权链接,登录您的 Google 账户并授权。',
step3EnterCode: '输入回调链接或 Code',
authCodeDesc: '授权完成后,复制浏览器跳转后的回调链接(推荐)或仅复制 <code>code</code>,粘贴到下方即可。',
authCodeDesc: '授权完成后,复制浏览器跳转后的回调链接(推荐)或仅复制 code粘贴到下方即可。',
authCode: '回调链接或 Code',
authCodePlaceholder: '方式1推荐粘贴回调链接\n方式2仅粘贴 code 参数的值',
authCodeHint: '系统会自动从链接中解析 code/state。',
@@ -1233,10 +1234,10 @@ export default {
step2OpenUrl: '在浏览器中打开链接并完成授权',
openUrlDesc: '请在新标签页中打开授权链接,登录您的 Google 账户并授权。',
importantNotice:
'<strong>重要提示:</strong>授权后页面可能会加载较长时间,请耐心等待。当浏览器地址栏变为 <code>http://localhost...</code> 开头时,表示授权已完成。',
'重要提示:授权后页面可能会加载较长时间,请耐心等待。当浏览器地址栏变为 http://localhost... 开头时,表示授权已完成。',
step3EnterCode: '输入授权链接或 Code',
authCodeDesc:
'授权完成后,当页面地址变为 <code>http://localhost:xxx/auth/callback?code=...</code> 时:',
'授权完成后,当页面地址变为 http://localhost:xxx/auth/callback?code=... 时:',
authCode: '授权链接或 Code',
authCodePlaceholder:
'方式1复制完整的链接\n(http://localhost:xxx/auth/callback?code=...)\n方式2仅复制 code 参数的值',
@@ -1576,7 +1577,8 @@ export default {
siteKey: '站点密钥',
secretKey: '私密密钥',
siteKeyHint: '从 Cloudflare Dashboard 获取',
secretKeyHint: '服务端验证密钥(请保密)'
secretKeyHint: '服务端验证密钥(请保密)',
secretKeyConfiguredHint: '密钥已配置,留空以保留当前值。'
},
defaults: {
title: '用户默认设置',
@@ -1626,6 +1628,8 @@ export default {
password: 'SMTP 密码',
passwordPlaceholder: '********',
passwordHint: '留空以保留现有密码',
passwordConfiguredPlaceholder: '********',
passwordConfiguredHint: '密码已配置,留空以保留当前值。',
fromEmail: '发件人邮箱',
fromEmailPlaceholder: "noreply{'@'}example.com",
fromName: '发件人名称',