feat: access token (#1320)
Co-authored-by: sealday <sealday@gmail.com> Reviewed-on: daoyoucloud/tachybase#1320
This commit is contained in:
parent
3a1e3d92e6
commit
90a09dfa40
@ -92,5 +92,10 @@ export default {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
hidden: true,
|
hidden: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'accessToken',
|
||||||
|
type: 'string',
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
} as CollectionOptions;
|
} as CollectionOptions;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { createHash } from 'crypto';
|
||||||
import actions, { Context, Next } from '@tachybase/actions';
|
import actions, { Context, Next } from '@tachybase/actions';
|
||||||
import { Repository } from '@tachybase/database';
|
import { Repository } from '@tachybase/database';
|
||||||
|
|
||||||
@ -18,13 +19,19 @@ export async function create(ctx: Context, next: Next) {
|
|||||||
throw ctx.throw(400, ctx.t('Role not found'));
|
throw ctx.throw(400, ctx.t('Role not found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = ctx.app.authManager.jwt.sign(
|
const hash = createHash('sha256');
|
||||||
|
const jwtToken = ctx.app.authManager.jwt.sign(
|
||||||
{ userId: ctx.auth.user.id, roleName: role.name },
|
{ userId: ctx.auth.user.id, roleName: role.name },
|
||||||
{ expiresIn: values.expiresIn },
|
{ expiresIn: values.expiresIn },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
hash.update(jwtToken);
|
||||||
|
const token = hash.digest('hex');
|
||||||
|
|
||||||
ctx.action.mergeParams({
|
ctx.action.mergeParams({
|
||||||
values: {
|
values: {
|
||||||
token,
|
token: jwtToken,
|
||||||
|
accessToken: token,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return actions.create(ctx, async () => {
|
return actions.create(ctx, async () => {
|
||||||
|
@ -22,6 +22,30 @@ export class PluginAPIKeysServer extends Plugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
|
const repo = this.db.getRepository('apiKeys');
|
||||||
|
this.app.resourcer.use(
|
||||||
|
async (ctx, next) => {
|
||||||
|
const token = ctx.getBearerToken();
|
||||||
|
// TODO 固定长度判断来优化性能
|
||||||
|
if (token && token.length !== 64) {
|
||||||
|
return await next();
|
||||||
|
}
|
||||||
|
const key = await repo.findOne({
|
||||||
|
filter: {
|
||||||
|
accessToken: token,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
ctx.getBearerToken = () => {
|
||||||
|
if (key) {
|
||||||
|
return key.token;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
};
|
||||||
|
|
||||||
|
await next();
|
||||||
|
},
|
||||||
|
{ tag: 'api-access-token', before: 'auth' },
|
||||||
|
);
|
||||||
this.app.resourcer.use(async (ctx, next) => {
|
this.app.resourcer.use(async (ctx, next) => {
|
||||||
const { resourceName, actionName } = ctx.action;
|
const { resourceName, actionName } = ctx.action;
|
||||||
if (resourceName === this.resourceName && ['list', 'destroy'].includes(actionName)) {
|
if (resourceName === this.resourceName && ['list', 'destroy'].includes(actionName)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user