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

使用fastify-jwt生成含用户ID的Token时报“Expected "options" to be a plain object”错误的解决方法

解决Fastify JWT登录功能的500错误问题

嘿,我来帮你搞定这个登录功能的问题~

错误原因分析

你遇到的"Expected 'options' to be a plain object."错误,核心问题出在两个地方:

  • fastify-jwt的sign方法第二个参数需要是配置选项对象(比如设置过期时间、算法等),而不是直接传入字符串密钥。你已经在注册插件时全局配置了密钥,调用sign时完全不需要重复传入密钥。
  • 代码缺少边界处理:如果用户输入的邮箱/密码错误,foundUser会是undefined,这时候直接解构{ id }会抛出新的异常,直接触发500错误。

修正后的完整代码

import Fastify from "fastify";
import fastifyJwt from "fastify-jwt";
import { users } from "../dummy-data/users.js";

const fastify = Fastify();
const SECRET_KEY = "secret";

// 全局注册JWT插件并配置密钥
fastify.register(fastifyJwt, { secret: SECRET_KEY });

// 注册登录路由,确保请求能映射到处理函数
fastify.post('/signin', signIn);

const signIn = function (req, res) {
  const { email, password } = req.body;

  // 1. 先校验请求参数是否完整
  if (!email || !password) {
    return res.status(400).send({ message: "邮箱和密码不能为空" });
  }

  // 2. 查找匹配的用户
  const foundUser = users.find(
    (user) => user.email === email && user.password === password
  );

  // 3. 处理用户不存在/密码错误的情况
  if (!foundUser) {
    return res.status(401).send({ message: "邮箱或密码错误" });
  }

  // 4. 生成Token:只传入包含用户ID的payload即可
  const accessToken = fastify.jwt.sign({ id: foundUser.id });
  
  return res.status(200).send({ accessToken });
}

// 启动Fastify服务
fastify.listen({ port: 3000 }, (err) => {
  if (err) {
    fastify.log.error(err);
    process.exit(1);
  }
  console.log('服务已启动在 http://localhost:3000');
});

关键修改点说明

  • 修正JWT签名调用:去掉了sign方法的第二个密钥参数,只传入用户ID的payload即可。因为插件已经全局配置了secret,会自动使用该密钥完成签名。如果需要临时使用不同密钥,才需要在第二个参数对象里指定secret,比如fastify.jwt.sign({ id }, { secret: "another-secret" })。
  • 增加参数校验:提前检查请求体的邮箱和密码是否存在,返回400错误提示,避免无效查询。
  • 增加错误边界处理:当未找到匹配用户时,返回401未授权错误,避免解构foundUser.id时抛出异常。
  • 补充路由注册:补上了你之前省略的路由注册代码,确保前端请求能正确触发signIn处理函数。

内容的提问来源于stack exchange,提问作者Evan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:37:33