feat: 在后台管理面板增加 API Token 配置与生成功能

This commit is contained in:
seahi committed 2026-09-21 19:40:58 +08:00
1 parent fe08cd27ff
commit 3f91f38a88
2 files changed
+76

No files matched your search

+22
View File
@@ -68,6 +68,28 @@ export const actions: Actions = {
return fail(500, { error: '保存站点信息失败' }); return fail(500, { error: '保存站点信息失败' });
} }
}, },
updateApiToken: async ({ request, platform }) => {
const db = platform?.env?.DB;
if (!db) return fail(500, { error: '数据库未连接' });
const data = await request.formData();
const token = data.get('agent_api_token')?.toString() || '';
try {
await db
.prepare(
`INSERT INTO settings (key, value, updated_at)
VALUES (?, ?, CURRENT_TIMESTAMP)
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = CURRENT_TIMESTAMP`
)
.bind('agent.api_token', token)
.run();
return { success: true };
} catch (err: unknown) {
console.error('Failed to update api token', err);
return fail(500, { error: '保存 API Token 失败' });
}
},
updateAliases: async ({ request, platform }) => { updateAliases: async ({ request, platform }) => {
const db = platform?.env?.DB; const db = platform?.env?.DB;
if (!db) return fail(500, { error: '数据库未连接' }); if (!db) return fail(500, { error: '数据库未连接' });
+54
View File
@@ -16,6 +16,17 @@
let avatarEnabled = $state(initialData.settings['site.avatar_enabled'] !== 'false'); let avatarEnabled = $state(initialData.settings['site.avatar_enabled'] !== 'false');
let avatarUrl = $state(initialData.settings['site.avatar_url'] || ''); let avatarUrl = $state(initialData.settings['site.avatar_url'] || '');
let apiToken = $state(initialData.settings['agent.api_token'] || '');
let showApiToken = $state(false);
function generateApiToken() {
const randomPart = Array.from(crypto.getRandomValues(new Uint8Array(16)))
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
apiToken = 'bf_agent_' + randomPart;
showApiToken = true;
}
$effect(() => { $effect(() => {
if (form?.success) { if (form?.success) {
addToast('设置保存成功!', 'success'); addToast('设置保存成功!', 'success');
@@ -131,6 +142,49 @@
<span class="value">Cloudflare Access (Zero Trust)</span> <span class="value">Cloudflare Access (Zero Trust)</span>
</div> </div>
</div> </div>
<div class="settings-card full-width">
<h3>API 与 AI 集成 (Agent/MCP)</h3>
<p class="desc">
配置允许 AI 或第三方工具直接管理文章的 API 访问令牌 (Token)。请求 API 时请在 HTTP Header
中添加 <code>Authorization: Bearer &lt;Token&gt;</code>。
</p>
<form
method="POST"
action="?/updateApiToken"
use:enhance={() => {
return async ({ update }) => {
update({ reset: false });
};
}}
class="alias-form"
>
<div class="form-group">
<label for="agent_api_token">API Token</label>
<div style="display: flex; gap: 10px; align-items: center; width: 100%;">
<TextInput
type={showApiToken ? 'text' : 'password'}
id="agent_api_token"
name="agent_api_token"
bind:value={apiToken}
placeholder="留空则禁用对外 API 访问"
/>
<Button
type="button"
variant="secondary"
onclick={() => (showApiToken = !showApiToken)}
>
{showApiToken ? '隐藏' : '显示'}
</Button>
<Button type="button" variant="secondary" onclick={generateApiToken}>自动生成</Button>
</div>
</div>
<div class="form-actions">
<Button type="submit" variant="primary">保存 Token</Button>
</div>
</form>
</div>
{/if} {/if}
{#if activeTab === 'appearance'} {#if activeTab === 'appearance'}