FeathersJS 5如何为服务创建自定义路径?JWT认证加载异常求助
问题描述
我在Feathers应用中创建了jobs服务,可通过/jobs端点执行CRUD操作。现在需要新增/getJobsCount端点,但添加JWT认证后请求一直处于加载状态,无认证时能正常返回结果。
现有代码
jobs.js
// For more information about this file see https://dove.feathersjs.com/guides/cli/service.html import { authenticate } from '@feathersjs/authentication' import { hooks as schemaHooks } from '@feathersjs/schema' import { jobsDataValidator, jobsPatchValidator, jobsQueryValidator, jobsResolver, jobsExternalResolver, jobsDataResolver, jobsPatchResolver, jobsQueryResolver } from './jobs.schema.js' import { JobsService, getOptions } from './jobs.class.js' import { jobsPath, jobsMethods } from './jobs.shared.js' export * from './jobs.class.js' export * from './jobs.schema.js' // A configure function that registers the service and its hooks via `app.configure` export const jobs = (app) => { // Register our service on the Feathers application app.use(jobsPath, new JobsService(getOptions(app)), { // A list of all methods this service exposes externally methods: jobsMethods, // You can add additional custom events to be sent to clients here events: [] }) // Initialize hooks app.service(jobsPath).hooks({ around: { all: [ authenticate('jwt'), schemaHooks.resolveExternal(jobsExternalResolver), schemaHooks.resolveResult(jobsResolver) ] }, before: { all: [schemaHooks.validateQuery(jobsQueryValidator), schemaHooks.resolveQuery(jobsQueryResolver)], find: [], get: [], create: [schemaHooks.validateData(jobsDataValidator), schemaHooks.resolveData(jobsDataResolver)], patch: [schemaHooks.validateData(jobsPatchValidator), schemaHooks.resolveData(jobsPatchResolver)], remove: [] }, after: { all: [] }, error: { all: [] } }) app.get('/getJobsCount', authentication("jwt") async (req, res) => { try { const jobsService = new JobsService(getOptions(app)) const count = await jobsService.getJobsCount() res.status(200).json(count) } catch (error) { res.status(500).json({ error: 'Server error' }) } }) }
jobs.class.js
async getJobsCount() { try { const jobsCount = await this.Model.count('id as count').from('jobs') return jobsCount[0].count } catch (error) { console.error('Error fetching office count:', error) throw new Error('Failed to fetch office count') } }
问题原因及修复方案
1. 路由认证中间件使用错误
自定义路由里存在三个问题:
- 拼写错误:
authentication应为authenticate - Feathers的
authenticate是hook,不能直接传入Express路由,需要用app.authenticate('jwt')生成符合Express规范的中间件 - 中间件与处理函数的链式写法错误,导致请求被挂起
2. 不必要的服务实例化
重新创建JobsService实例会绕过服务已配置的hooks和上下文,直接使用已注册的服务实例更合理。
修改后的自定义路由代码
// 生成JWT认证中间件 const authenticateJwt = app.authenticate('jwt'); app.get('/getJobsCount', authenticateJwt, async (req, res) => { try { // 获取已注册的jobs服务实例 const jobsService = app.service(jobsPath); const count = await jobsService.getJobsCount(); res.status(200).json({ count }); } catch (error) { console.error('获取任务数量失败:', error); res.status(500).json({ error: '服务器内部错误' }); } });
更符合Feathers架构的方案
推荐直接在jobs服务中新增自定义方法,复用已有的认证hook,无需单独写Express路由:
步骤1:更新jobs.shared.js,添加自定义方法
export const jobsMethods = ['find', 'get', 'create', 'patch', 'remove', 'count'];
步骤2:修改jobs.class.js,重命名方法为count
async count() { try { const jobsCount = await this.Model.count('id as count').from('jobs'); return { count: jobsCount[0].count }; } catch (error) { console.error('获取任务数量失败:', error); throw new Error('Failed to fetch jobs count'); } }
步骤3:访问端点
现在可以通过GET /jobs/count访问,自动应用已配置的JWT认证hook,无需额外处理。
内容的提问来源于stack exchange,提问作者Daniel Tršťanský
相关产品推荐
相关产品推荐

