我正在尝试使用passport-jwt和passport-local-mongoose创建一个简单的API,我设置了所有的JWT功能并建立了一些路由,例如一个注册路径和一个登录路径!这些路由中的一个ogf会收到一个get请求,以列出数据库中存在的所有文档,但是,当我尝试发出此请求时,服务器给了我这个错误:
DError [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:533:11)
at ServerResponse.header (/home/mdsp/Documents/Challenges/passportJWTMongoose/node_modules/express/lib/response.js:771:10)
at ServerResponse.json (/home/mdsp/Documents/Challenges/passportJWTMongoose/node_modules/express/lib/response.js:264:10)
at /home/mdsp/Documents/Challenges/passportJWTMongoose/src/controllers/Document.ts:9:18
at step (/home/mdsp/Documents/Challenges/passportJWTMongoose/src/controllers/Document.ts:33:23)
at Object.next (/home/mdsp/Documents/Challenges/passportJWTMongoose/src/controllers/Document.ts:14:53)
at fulfilled (/home/mdsp/Documents/Challenges/passportJWTMongoose/src/controllers/Document.ts:5:58)
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
code: 'ERR_HTTP_HEADERS_SENT'
}
我对此进行了搜索,发现该错误通常是由于双重回调或类似原因引起的,但是我无法指定错误的出处以及为什么在我的代码中发生此错误。这是Document控制器:
import { Request, Response } from "express";
import DocumentModel from "../database/models/Document";
class Document {
async index(req: Request, res: Response) {
try {
const documents = await DocumentModel.find();
return res.status(200).json(documents);
} catch (err) {
console.log(err);
return res.status(400).json({ error: err.message });
}
}
}
export default new Document();
这是我的路线文件:
import { Router } from "express";
import auth from "./middleware/auth";
import documentController from "./controllers/Document";
const router = Router();
router.get("/", (req, res) => {
return res.json({ home: "My homepage" });
});
router.get("/documents", auth.requireJWT, documentController.index);
router.post("/auth/register", auth.register, auth.signJWTForUser);
router.post("/auth", auth.signIn, auth.signJWTForUser);
export default router;
这是auth.ts,我在其中配置了所有passport和JWT函数以进行拒绝,登录和请求JWT令牌:
import { config } from "dotenv";
config();
import passport from "passport";
import JWT from "jsonwebtoken";
import { Strategy, ExtractJwt } from "passport-jwt";
import { Request, Response, NextFunction } from "express";
import UserModel from "../database/models/User";
interface IRequestUser extends Express.User {
_id?: string;
email?: string;
firstName?: string;
lastName?: string;
}
const jwtSecret = process.env.JWT_SECRET!;
const jwtAlgorithm = "HS256";
const jwtExpiresIn = "7 days";
passport.use(UserModel.createStrategy());
async function register(req: Request, res: Response, next: NextFunction) {
try {
const { email, firstName, lastName, password } = req.body;
const user = new UserModel({
email: email,
firstName: firstName,
lastName: lastName,
});
const registeredUser = await UserModel.register(user, password);
req.user = registeredUser;
return next();
} catch (err) {
console.log(err.message);
return next(err);
}
}
passport.use(
new Strategy(
{
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: jwtSecret,
algorithms: [jwtAlgorithm],
},
async (payload, done) => {
try {
const foundUser = await UserModel.findById(payload.sub);
foundUser && done(null, foundUser);
done(null, false);
} catch (err) {
console.log(err.message);
done(err, false);
}
}
)
);
function signJWTForUser(req: Request, res: Response) {
if (req.user) {
const user: IRequestUser = req.user;
const token = JWT.sign({ email: user.email }, jwtSecret, {
algorithm: jwtAlgorithm,
expiresIn: jwtExpiresIn,
subject: user._id!.toString(),
});
return res.json({ token });
}
}
export default {
initialize: passport.initialize(),
register,
signIn: passport.authenticate("local", { session: false }),
requireJWT: passport.authenticate("jwt", { session: false }),
signJWTForUser,
};
我应该在控制器上进行哪些改进以及导致此错误的原因?
答案 0 :(得分:2)
您的护照策略设置自定义回调在找到用户时会发送两个休止符。
const foundUser = await UserModel.findById(payload.sub);
foundUser && done(null, foundUser);
done(null, false); //<<<- HERE
我不是Passport.js专家-但是您应该按照文档将其调用一次。
const foundUser = await UserModel.findById(payload.sub);
done(null, foundUser);