我有一个中间件,在允许用户访问路由之前,它会检查用户是否已登录。它看起来像这样:
import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
const authenticate = (req: Authenticate, res: Response, next: NextFunction) => {
const token = req.cookies;
if (token) {
jwt.verify(token, process.env.JWT_TOKEN_KEY, (error, res) => {
if (error) return res.sendStatus(403);
req.cookie = { _id: res._id, locale: res.locale };
return next();
});
}
return res.sendStatus(401);
};
export default authenticate;
测试是:
import chai from "chai";
import chaiHttp from "chai-http";
import { server } from "../index";
chai.use(chaiHttp);
const api = chai.request(server).keepOpen();
describe("GET /user/:id", () => {
it("return user information", () => {
api
.get("/user/123")
.set("Cookie", "_id=567;locale=en")
.end(function (err, res) {
chai.expect(res).to.have.status(200);
});
});
});
如果我从路由中删除中间件,测试就可以正常工作。因此:
// OK
router.post("/user/:id", searchUser);
// NOT OK
router.post("/user/:id", authenticate, searchUser);
错误为:
TypeError:无法读取未定义的属性"sendStatus"在Object.module.exports[as-verify](/Users/myname/Desktop/Code/myapp/server/src/mediale/authenticate.ts:21:29(
jwt.verify()
回调函数的res
变量覆盖了authenticate
中间件的res
变量,这就是出现此错误的原因。您应该给它一个不同的名称以避免冲突。
我想你是从chai-http
拿到req.cookies
的。如果没有,您可能忘记使用cookie-parser
中间件。
例如
index.ts
:
import express from 'express';
import cookieParser from 'cookie-parser';
import authenticate from './mws/authenticate';
const server = express();
server.use(cookieParser());
server.get('/user/:id', authenticate, (req, res) => {
const { id } = req.params;
res.json({ id, name: 'teresa teng' });
});
export { server };
authenticate.ts
:
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
const authenticate = (req: Request, res: Response, next: NextFunction) => {
const token = req.cookies;
console.log('cookies: ', req.cookies);
if (token) {
jwt.verify(token, process.env.JWT_TOKEN_KEY, (error, verifyResponse) => {
if (error) return res.sendStatus(403);
req.cookies = { _id: verifyResponse._id, locale: verifyResponse.locale };
return next();
});
}
return res.sendStatus(401);
};
export default authenticate;
index.test.ts
:
import chai from 'chai';
import chaiHttp from 'chai-http';
import { server } from './';
chai.use(chaiHttp);
const api = chai.request(server).keepOpen();
describe('GET /user/:id', () => {
it('return user information', (done) => {
api
.get('/user/123')
.set('Cookie', '_id=567;locale=en')
.end(function (err, res) {
chai.expect(res).to.have.status(200);
done();
});
});
});
日志:
GET /user/:id
cookies: { _id: '567', locale: 'en' }
1) return user information