Feathers.js V5:不使用authenticate hook如何检查用户是否登录
在Feathers非受限路径中检查用户是否登录的方法
你说得没错,默认情况下只有authenticate('jwt')这类强制认证的hook会解析JWT并将用户信息填充到context.params中。如果想在非受限路径(比如无需强制登录即可访问的find接口)里可选性地检查用户是否登录,可以通过以下两种方式实现:
方式1:使用内置的parseJWT和populateUser hook
Feathers的认证模块提供了parseJWT和populateUser这两个底层hook,它们是authenticate hook的组成部分,但单独使用时不会强制拦截未登录请求——如果请求携带了有效的JWT,就会自动解析并填充用户信息;如果没有,也不会报错,context.params.user会保持undefined。
修改你的代码示例:
首先确保导入这两个hook:
const { parseJWT, populateUser, authenticate, iff, isProvider } = require('@feathersjs/authentication'); // 或者ES模块语法: // import { parseJWT, populateUser, authenticate, iff, isProvider } from '@feathersjs/authentication';
然后更新messages服务的before hook配置:
export const messages = app => { app.use('messages', new MessageService(getOptions(app)), { methods: ['find', 'get'], events: [] }) app.service('messages').hooks({ around: { all: [] }, before: { all: [], // 这里添加parseJWT和populateUser,实现可选认证 find: [ iff(isProvider('external'), parseJWT(), populateUser()), async cxt => { // 现在如果用户已登录,cxt.params.user会有值;未登录则为undefined console.log('当前用户:', cxt.params.user); } ], get: [ authenticate('jwt'), iff(isProvider('external'), async cxt => console.log(cxt.params.user))], }, after: {all: []}, error: {all: []} }) }
方式2:自定义简易检查hook
如果不需要完整的用户信息,只是想验证请求中是否携带了有效的JWT,可以自己写一个轻量的hook:
const checkOptionalAuth = async context => { const { app, params } = context; // 从请求头或查询参数中获取JWT(根据你的认证配置调整) const token = params.headers?.authorization?.split(' ')[1] || params.query?.token; if (token) { try { // 验证并解析JWT const payload = await app.get('authentication').verifyToken(token); // 可选:根据payload中的userId查询用户信息 params.user = await app.service('users').get(payload.userId); } catch (err) { // token无效时不报错,只是不填充用户信息 params.user = undefined; } } return context; };
然后在find hook中使用:
find: [ iff(isProvider('external'), checkOptionalAuth), async cxt => console.log('当前用户:', cxt.params.user) ],
这样就能在非受限接口中灵活判断用户是否已登录,而不会强制要求用户必须认证才能访问接口。
内容的提问来源于stack exchange,提问作者ramon22
相关产品推荐
相关产品推荐

