错误:"Reply was already sent." - 快速 - 无日志



我试图在Fastify中创建一个简单、肮脏的身份验证流。

值通过带有Postgres数据库的Prisma进行回签,通过bcrypt进行回签然后转换为JWT

这是代码:

const login: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
fastify.post("/", async function (request: any, reply) {
console.log("Request");
if (request.body.username && request.body.password) {
await prisma.user
.findFirst({
where: { name: request.body.username },
})
.then(async (user) => {
console.log("prisma");
if (!user?.id) {
console.log("User not found");
return reply.code(404).send({ message: "User not found" });
} else {
if (bcrypt.compareSync(request.body.password, user!.hash)) {
console.log("Password correct");
await jwt.sign(
{ user: user },
process.env.SECRET || "",
{ expiresIn: "365d" },
(err: any, token: any) => {
if (err) {
console.log("Error");
return reply.code(500).send({ message: "Error" });
} else {
console.log("JWT");
return reply.code(200).send({ jwt: token });
}
}
);
} else {
console.log("Password incorrect");
return reply.code(500).send({ message: "Password incorrect" });
}
}
});
} else {
console.log("Missing username or password");
return reply.code(400).send({ message: "Missing user or password" });
}
});
}

我尝试记录任何步骤,但没有抛出重复的日志。

这就是错误:

[App] Request
[App] prisma
[App] Password correct
[App] JWT
[23:29:19.419] INFO (23324): incoming request
[App]     reqId: "req-1"
[App]     req: {
[App]       "method": "POST",
[App]       "url": "/users/login",
[App]       "hostname": "127.0.0.1:3000",
[App]       "remoteAddress": "127.0.0.1",
[App]       "remotePort": 1042
[App]     }
[App] [23:29:19.576] WARN (23324): Reply already sent
[App]     reqId: "req-1"
[App]     err: {
[App]       "type": "FastifyError",
[App]       "message": "Reply was already sent.",
[App]       "stack":
[App]           FastifyError: Reply was already sent.
[App]               at _Reply.Reply.send (C:UsersmichaWebstormProjectsLIBManbackendnode_modulesfastifylibreply.js:118:26)
[App]               at C:UsersmichaWebstormProjectsLIBManbackenddistroutesusersloginindex.js:29:56       
[App]               at C:UsersmichaWebstormProjectsLIBManbackendnode_moduleslodash.onceindex.js:71:21      
[App]               at SignStream.<anonymous> (C:UsersmichaWebstormProjectsLIBManbackendnode_modulesjsonwebtokensign.js:201:9)
[App]               at Object.onceWrapper (node:events:642:26)
[App]               at SignStream.emit (node:events:527:28)
[App]               at SignStream.sign (C:UsersmichaWebstormProjectsLIBManbackendnode_modulesjwslibsign-stream.js:64:10)
[App]               at SignStream.<anonymous> (C:UsersmichaWebstormProjectsLIBManbackendnode_modulesjwslibsign-stream.js:46:12)
[App]               at Object.onceWrapper (node:events:641:28)

如果我遗漏了一些明显的东西,我会提前道歉请求返回空

正如您已经发现的,问题是async/await+than和回调的混合。

它导致代码难以阅读,并且有许多边缘情况,因为您不知道何时以及哪些代码将首先执行(回调或等待之后的语句(。

请注意,prisma查询上有相同的模式,而不仅仅是JWT代码上。

让我向您展示完全异步/等待风格的代码:

async function login(fastify, opts) {
fastify.post("/", async function (request, reply) {
console.log("Request");
// first thing first: we are avoiding to naste the code in if/else statements
if (!request.body.username || !request.body.password) {
console.log("Missing username or password");
return reply.code(400).send({ message: "Missing user or password" });
}
const user = await prisma.user.findFirst({
where: { name: request.body.username },
})
console.log("prisma");

if (!user?.id) {
console.log("User not found");
return reply.code(404).send({ message: "User not found" });
}
if (!bcrypt.compareSync(request.body.password, user.hash)) {
console.log("Password incorrect");
return reply.code(500).send({ message: "Password incorrect" });
}
console.log("Password correct");
const token = await jwt.sign(
{ user: user },
process.env.SECRET || "",
{ expiresIn: "365d" },
)
console.log("JWT");
// using async handlers, you can return a json instead of calling reply.send
return { jwt: token }
});
}

我在尝试了很多之后发现了我的错误:

Fastify不喜欢JWT代币签名过程是异步的,它似乎返回了两次。

这很简单,只需将JWT进程更改为不使用回调,而只是作为let返回即可。

请访问此答案。它更好、更详细地解释了

嘿,你的代码看起来有点乱,所以我可以自由地清理一下所有的东西,希望这能奏效。请告诉我问题是否仍然存在

const login: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
fastify.post("/", async function (request: any, reply) {
console.log("Request");
if (!request.body.username || !request.body.password) {
return reply.code(400).send({ message: "Missing user or password" });
}
const user = await prisma.user.findFirst({ where: { name: request.body.username }})

console.log("prisma");
if(!user?.id) {
console.log("User not found");
return reply.code(404).send({ message: "User not found" });
}
if (!bcrypt.compareSync(request.body.password, user!.hash)) {
console.log("Password incorrect");
return reply.code(500).send({ message: "Password incorrect" });
}
console.log("Password correct");
await jwt.sign({ user: user }, process.env.SECRET || "", { expiresIn: "365d" }, (err: any, token: any) => {
if (err) {
console.log("Error");
return reply.code(500).send({ message: "Error" });
}
console.log("JWT");
return reply.code(200).send({ jwt: token });
}
});

}

相关内容

  • 没有找到相关文章

最新更新