refactor: 彻底移除 apiSecret 认证方式,仅保留 Bearer + PSK

删除:
- HmacUtil: deriveApiKey/deriveApiSecret/verifyMediabotPsk
- HmacAuthInterceptor: apiSecret 验签/自动创建账户/readBody
- AccountService: generateApiCredentials/registerByInterceptor
- AccountDTO: apiKey 字段
- AuthController: register 返回 apiSecret
- AdminController: generateApiKey 端点
- Users.vue: API Key 列/生成密钥弹窗
- api/index.js: genApiKey

认证方式简化为两种:
  Bearer Token → Web 管理后台
  PSK 签名    → 外部集成客户端
This commit is contained in:
mediabot-pt
2026-06-29 16:56:00 +08:00
parent 5304449de6
commit 311ead0e89
10 changed files with 56 additions and 315 deletions

View File

@@ -45,7 +45,7 @@ export default {
users: {
list: () => api.get('/admin/accounts'),
setTrustLevel: (id, level) => api.post(`/admin/accounts/${id}/trust-level`, null, { params: { level } }),
genApiKey: (id) => api.post(`/admin/accounts/${id}/api-key`)
},
health: () => api.get('/health', { baseURL: '' })
}

View File

@@ -6,12 +6,6 @@
<el-table-column prop="id" label="ID" width="60" />
<el-table-column prop="email" label="邮箱" min-width="180" />
<el-table-column prop="displayName" label="昵称" width="120" />
<el-table-column label="API Key" min-width="180">
<template #default="scope">
<span v-if="scope.row.apiKey" style="font-family:monospace;font-size:12px">{{ scope.row.apiKey }}</span>
<el-tag v-else size="small" type="info">未生成</el-tag>
</template>
</el-table-column>
<el-table-column prop="trustLevel" label="信任等级" width="90">
<template #default="scope">
<el-tag :type="trustLevelType(scope.row.trustLevel)">
@@ -27,45 +21,19 @@
</template>
</el-table-column>
<el-table-column prop="createdAt" label="注册时间" width="160" />
<el-table-column label="操作" width="200" fixed="right">
<el-table-column label="操作" width="120" fixed="right">
<template #default="scope">
<el-button size="small" @click="handleGenKey(scope.row)">生成密钥</el-button>
<el-button
v-if="scope.row.trustLevel !== 'ADMIN'"
size="small"
@click="handleSetLevel(scope.row)"
>设置等级</el-button>
<span v-else style="color:#999;font-size:12px">管理员</span>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- API Key 弹窗 -->
<el-dialog v-model="keyDialogVisible" title="API Key" width="500px" :close-on-click-modal="false">
<el-alert type="warning" :closable="false" style="margin-bottom:16px">
Secret 仅在生成时显示一次,请立即复制保存!
</el-alert>
<el-form label-width="80px">
<el-form-item label="API Key">
<el-input v-model="keyResult.apiKey" readonly>
<template #append>
<el-button @click="copyText(keyResult.apiKey)">复制</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="API Secret">
<el-input v-model="keyResult.apiSecret" readonly type="textarea" :rows="2">
<template #append>
<el-button @click="copyText(keyResult.apiSecret)">复制</el-button>
</template>
</el-input>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="keyDialogVisible = false">关闭</el-button>
</template>
</el-dialog>
<!-- 等级设置弹窗 -->
<el-dialog v-model="dialogVisible" title="设置信任等级" width="400px">
<el-form :model="levelForm">
@@ -95,9 +63,6 @@ const loading = ref(false)
const dialogVisible = ref(false)
const saving = ref(false)
const levelForm = reactive({ id: null, email: '', level: '' })
const keyDialogVisible = ref(false)
const keyResult = reactive({ apiKey: '', apiSecret: '' })
const trustLevelType = (level) => {
const map = { MEMBER: '', TRUSTED: 'warning', ADMIN: 'danger' }
return map[level] || ''
@@ -120,22 +85,6 @@ const fetchUsers = async () => {
}
}
const handleGenKey = async (row) => {
try {
const res = await api.users.genApiKey(row.id)
keyResult.apiKey = res.data.apiKey
keyResult.apiSecret = res.data.apiSecret
keyDialogVisible.value = true
fetchUsers()
} catch (e) {
ElMessage.error(e.response?.data?.message || '生成失败')
}
}
const copyText = (text) => {
navigator.clipboard.writeText(text).then(() => ElMessage.success('已复制'))
}
const handleSetLevel = (row) => {
levelForm.id = row.id
levelForm.email = row.email