1
This commit is contained in:
3
_docs/sql/biz_api_token_key.sql
Normal file
3
_docs/sql/biz_api_token_key.sql
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
-- token 绑定账号唯一标识 key(供转发时自动拼到 query.key)
|
||||||
|
ALTER TABLE biz_api_token
|
||||||
|
ADD COLUMN `key` VARCHAR(128) NULL COMMENT '账号唯一标识' AFTER token_name;
|
||||||
@@ -59,6 +59,7 @@
|
|||||||
<Option v-for="u in bizUserOptions" :key="u.id" :value="u.id">{{ bizUserLabel(u) }}</Option>
|
<Option v-for="u in bizUserOptions" :key="u.id" :value="u.id">{{ bizUserLabel(u) }}</Option>
|
||||||
</Select>
|
</Select>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
<FormItem label="账号 key"><Input v-model="createForm.key" placeholder="账号唯一标识(可选)" /></FormItem>
|
||||||
<FormItem label="名称"><Input v-model="createForm.token_name" placeholder="default" /></FormItem>
|
<FormItem label="名称"><Input v-model="createForm.token_name" placeholder="default" /></FormItem>
|
||||||
<FormItem label="过期时间"><Input v-model="createForm.expire_at" placeholder="2026-12-31 23:59:59" /></FormItem>
|
<FormItem label="过期时间"><Input v-model="createForm.expire_at" placeholder="2026-12-31 23:59:59" /></FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
@@ -104,6 +105,7 @@ export default {
|
|||||||
{ title: 'ID', key: 'id', width: 70 },
|
{ title: 'ID', key: 'id', width: 70 },
|
||||||
{ title: '用户', key: 'user_id', width: 90 },
|
{ title: '用户', key: 'user_id', width: 90 },
|
||||||
{ title: '套餐', key: 'plan_id', width: 90 },
|
{ title: '套餐', key: 'plan_id', width: 90 },
|
||||||
|
{ title: 'Key', key: 'key', minWidth: 140 },
|
||||||
{ title: '名称', key: 'token_name', width: 120 },
|
{ title: '名称', key: 'token_name', width: 120 },
|
||||||
{ title: '状态', key: 'status', width: 90 },
|
{ title: '状态', key: 'status', width: 90 },
|
||||||
{ title: '过期', key: 'expire_at', minWidth: 150 },
|
{ title: '过期', key: 'expire_at', minWidth: 150 },
|
||||||
@@ -176,7 +178,7 @@ export default {
|
|||||||
2,
|
2,
|
||||||
'0'
|
'0'
|
||||||
)} 23:59:59`
|
)} 23:59:59`
|
||||||
this.createForm = { user_id: undefined, token_name: 'default', expire_at: fmt }
|
this.createForm = { user_id: undefined, key: '', token_name: 'default', expire_at: fmt }
|
||||||
this.createModal = true
|
this.createModal = true
|
||||||
},
|
},
|
||||||
submitCreate() {
|
submitCreate() {
|
||||||
@@ -194,6 +196,7 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const res = await tokenServer.create({
|
const res = await tokenServer.create({
|
||||||
user_id: Number(uid),
|
user_id: Number(uid),
|
||||||
|
key: this.createForm.key || null,
|
||||||
token_name: this.createForm.token_name || 'default',
|
token_name: this.createForm.token_name || 'default',
|
||||||
expire_at: this.createForm.expire_at,
|
expire_at: this.createForm.expire_at,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ module.exports = {
|
|||||||
id: result.row.id,
|
id: result.row.id,
|
||||||
user_id: result.row.user_id,
|
user_id: result.row.user_id,
|
||||||
plan_id: result.row.plan_id,
|
plan_id: result.row.plan_id,
|
||||||
|
key: result.row.key,
|
||||||
token_name: result.row.token_name,
|
token_name: result.row.token_name,
|
||||||
expire_at: result.row.expire_at,
|
expire_at: result.row.expire_at,
|
||||||
plain_token: result.plain_token,
|
plain_token: result.plain_token,
|
||||||
|
|||||||
@@ -65,8 +65,11 @@ function buildProxyRoutes() {
|
|||||||
ctx.fail(authResult.message || "鉴权失败");
|
ctx.fail(authResult.message || "鉴权失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 3. 组装 query
|
// 3. 组装 query,并注入 token 对应 key(上游要求参数名为 key)
|
||||||
const query = { ...ctx.query };
|
const query = { ...ctx.query };
|
||||||
|
if (!query.key && authResult.context && authResult.context.token_key) {
|
||||||
|
query.key = authResult.context.token_key;
|
||||||
|
}
|
||||||
|
|
||||||
// 4. 转发到上游
|
// 4. 转发到上游
|
||||||
const result = await proxy.forwardRequest({
|
const result = await proxy.forwardRequest({
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ module.exports = (db) => {
|
|||||||
allowNull: false,
|
allowNull: false,
|
||||||
defaultValue: "",
|
defaultValue: "",
|
||||||
},
|
},
|
||||||
|
key: {
|
||||||
|
type: Sequelize.STRING(128),
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
token_hash: {
|
token_hash: {
|
||||||
type: Sequelize.STRING(64),
|
type: Sequelize.STRING(64),
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
@@ -42,6 +46,6 @@ module.exports = (db) => {
|
|||||||
underscored: true,
|
underscored: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// biz_api_token.sync({ force: true });
|
//biz_api_token.sync({ force: true });
|
||||||
return biz_api_token;
|
return biz_api_token;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ async function verifyRequest(body) {
|
|||||||
plan_id: sub.plan_id,
|
plan_id: sub.plan_id,
|
||||||
subscription_id: sub.id,
|
subscription_id: sub.id,
|
||||||
token_id: row.id,
|
token_id: row.id,
|
||||||
|
token_key: row.key || "",
|
||||||
stat_month: statMonth,
|
stat_month: statMonth,
|
||||||
usage_snapshot: {
|
usage_snapshot: {
|
||||||
msg_count: usageSvc.num(usageRow.msg_count),
|
msg_count: usageSvc.num(usageRow.msg_count),
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ async function findActiveSubscriptionForUser(userId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function createToken(body) {
|
async function createToken(body) {
|
||||||
const { user_id, token_name, expire_at } = body;
|
const { user_id, token_name, expire_at, key } = body;
|
||||||
if (!user_id || !expire_at) throw new Error("缺少 user_id 或 expire_at");
|
if (!user_id || !expire_at) throw new Error("缺少 user_id 或 expire_at");
|
||||||
const u = await baseModel.biz_user.findByPk(user_id);
|
const u = await baseModel.biz_user.findByPk(user_id);
|
||||||
if (!u) throw new Error("用户不存在");
|
if (!u) throw new Error("用户不存在");
|
||||||
@@ -60,6 +60,7 @@ async function createToken(body) {
|
|||||||
user_id,
|
user_id,
|
||||||
plan_id,
|
plan_id,
|
||||||
token_name: token_name || "default",
|
token_name: token_name || "default",
|
||||||
|
key: key || null,
|
||||||
token_hash,
|
token_hash,
|
||||||
secret_cipher,
|
secret_cipher,
|
||||||
status: "active",
|
status: "active",
|
||||||
|
|||||||
Reference in New Issue
Block a user