You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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ý

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:30:27