Chai 测试没有通过 cookie 认证中间件
Chai test doesn't pass the cookie authentification middleware
我有一个中间件可以在让用户访问路由之前检查用户是否已登录。它看起来像这样:
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: Cannot read property 'sendStatus' of undefined
at /Users/myname/Desktop/Code/myapp/server/src/middleware/authenticate.ts:21:29 at Object.module.exports [as verify] (/Users/myname/Desktop/Code/myapp/server/node_modules/jsonwebtoken/verify.js:57:12)
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
我有一个中间件可以在让用户访问路由之前检查用户是否已登录。它看起来像这样:
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: Cannot read property 'sendStatus' of undefined at /Users/myname/Desktop/Code/myapp/server/src/middleware/authenticate.ts:21:29 at Object.module.exports [as verify] (/Users/myname/Desktop/Code/myapp/server/node_modules/jsonwebtoken/verify.js:57:12)
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