feat: jwt service
This commit is contained in:
parent
e8a7e321f0
commit
c6f1454ae8
@ -45,18 +45,43 @@ const plugins = [
|
||||
'@nocobase/plugin-ui-routes-storage',
|
||||
'@nocobase/plugin-file-manager',
|
||||
'@nocobase/plugin-system-settings',
|
||||
[
|
||||
'@nocobase/plugin-users',
|
||||
{
|
||||
jwt: {
|
||||
secret: process.env.JWT_SECRET || '09f26e402586e2faa8da4c98a35f1b20d6b033c60',
|
||||
},
|
||||
installing: {
|
||||
adminNickname: 'Super Admin',
|
||||
adminEmail: 'admin@nocobase.com',
|
||||
adminPassword: 'admin123',
|
||||
},
|
||||
},
|
||||
],
|
||||
'@nocobase/plugin-acl',
|
||||
'@nocobase/plugin-china-region',
|
||||
'@nocobase/plugin-workflow',
|
||||
[
|
||||
'@nocobase/plugin-client',
|
||||
{
|
||||
dist: resolve(__dirname, '../../app/dist'),
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
for (const plugin of plugins) {
|
||||
if (Array.isArray(plugin)) {
|
||||
api.plugin(require(plugin.shift() as string).default, plugin.shift());
|
||||
} else {
|
||||
api.plugin(require(plugin).default);
|
||||
}
|
||||
}
|
||||
|
||||
api.plugin(require('@nocobase/plugin-client').default, {
|
||||
dist: resolve(__dirname, '../../app/dist'),
|
||||
api.acl.use(async (ctx, next) => {
|
||||
ctx.permission = {
|
||||
skip: true,
|
||||
};
|
||||
await next();
|
||||
});
|
||||
|
||||
if (process.argv.length < 3) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import * as jwt from 'jsonwebtoken';
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
export interface JwtOptions {
|
||||
secret: string;
|
||||
|
@ -1,14 +1,9 @@
|
||||
import { Context, Next } from '@nocobase/actions';
|
||||
import UsersPlugin from '../server';
|
||||
|
||||
// TODO(feature): 表名应在 options 中配置
|
||||
// 中间件默认只解决解析 token 和附加对应 user 的工作,不解决是否提前报 401 退出。
|
||||
|
||||
// 因为是否提供匿名访问资源是应用决定的,不是使用插件就一定不能匿名访问。
|
||||
export function parseToken(options?: any) {
|
||||
export function parseToken(options?: { plugin: UsersPlugin }) {
|
||||
return async function parseToken(ctx: Context, next: Next) {
|
||||
const user = await findUserByToken(ctx);
|
||||
|
||||
const user = await findUserByToken(ctx, options.plugin);
|
||||
if (user) {
|
||||
ctx.state.currentUser = user;
|
||||
setCurrentRole(ctx, user);
|
||||
@ -33,15 +28,13 @@ function setCurrentRole(ctx, user) {
|
||||
}
|
||||
}
|
||||
|
||||
async function findUserByToken(ctx: Context) {
|
||||
const token = getTokenFromCtx(ctx);
|
||||
async function findUserByToken(ctx: Context, plugin: UsersPlugin) {
|
||||
const token = ctx.getBearerToken();
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const pluginUser = ctx.app.getPlugin('@nocobase/plugin-users');
|
||||
|
||||
const { userId } = await pluginUser.jwtService.decode(token);
|
||||
try {
|
||||
const { userId } = await plugin.jwtService.decode(token);
|
||||
|
||||
return await ctx.db.getRepository('users').findOne({
|
||||
filter: {
|
||||
@ -49,8 +42,7 @@ async function findUserByToken(ctx: Context) {
|
||||
},
|
||||
appends: ['roles'],
|
||||
});
|
||||
}
|
||||
|
||||
function getTokenFromCtx(ctx: Context) {
|
||||
return ctx.get('Authorization').replace(/^Bearer\s+/gi, '');
|
||||
} catch (error) {
|
||||
console.warn(error);
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ import { Collection } from '@nocobase/database';
|
||||
import { Plugin } from '@nocobase/server';
|
||||
import { resolve } from 'path';
|
||||
import * as actions from './actions/users';
|
||||
import * as middlewares from './middlewares';
|
||||
import { JwtOptions, JwtService } from './jwt-service';
|
||||
import * as middlewares from './middlewares';
|
||||
|
||||
export interface UserPluginConfig {
|
||||
jwt: JwtOptions;
|
||||
@ -76,7 +76,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
this.app.resourcer.registerActionHandler(`users:${key}`, action);
|
||||
}
|
||||
|
||||
this.app.resourcer.use(middlewares.parseToken());
|
||||
this.app.resourcer.use(middlewares.parseToken({ plugin: this }));
|
||||
|
||||
const publicActions = ['check', 'signin', 'signup', 'lostpassword', 'resetpassword', 'getUserByResetToken'];
|
||||
const loggedInActions = ['signout', 'updateProfile', 'changePassword', 'setDefaultRole'];
|
||||
@ -100,7 +100,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
adminNickname = 'Super Admin',
|
||||
adminEmail = 'admin@nocobase.com',
|
||||
adminPassword = 'admin123',
|
||||
} = this.options.installing;
|
||||
} = this.options.installing || {};
|
||||
|
||||
return {
|
||||
adminNickname,
|
||||
|
@ -110,6 +110,9 @@ export function registerMiddlewares(app: Application, options: ApplicationOption
|
||||
);
|
||||
|
||||
app.use<DefaultState, DefaultContext>(async (ctx, next) => {
|
||||
ctx.getBearerToken = () => {
|
||||
return ctx.get('Authorization').replace(/^Bearer\s+/gi, '');
|
||||
};
|
||||
ctx.db = app.db;
|
||||
ctx.resourcer = app.resourcer;
|
||||
const i18n = app.i18n.cloneInstance({ initImmediate: false });
|
||||
|
Loading…
Reference in New Issue
Block a user