DoneDeal0
DoneDeal0

Reputation: 6257

How to set a jwt cookie with mocha/chai?

I need to test protected routes with mocha and chai. The authentication middleware crashes all the time with an error 500 because jwt must be a string.

When the user logs-in, he receives an http-only cookie whose data is a jwt token. The cookie is automatically sent to the server on each request thanks to axios withCredentials: true property.

So, I've tried to set a cookie or an auth bearer to my test, but without any success so far. How to fix this?

Here is what I've written:

import chai from "chai";
import chaiHttp from "chai-http";
import { app } from "../index";
import jwt from "jsonwebtoken";

chai.use(chaiHttp);
const api = chai.request(app).keepOpen();
const token = jwt.sign(
  { _id: "123", locale: "en" },
  process.env.JWT_TOKEN_KEY,
  {
    expiresIn: "14d",
  }
);

describe("GET /user/:id", () => {
  it("return user information", (done) => {
    api
      .get("/user/123")
      .set("Cookie", token)
      .end((err, res) => {
        chai.expect(res).to.have.status(200);
        done();
      });
  });
});

The middleware is:

import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
import { Cookie } from "../models/Cookie";

interface Authenticate extends Request {
  cookie: Cookie;
  cookies: any;
}

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;

I've been stuck on testing my api routes since 48 hours. Any help would be highly appreciated.

Upvotes: 1

Views: 1211

Answers (1)

lifeisfoo
lifeisfoo

Reputation: 16314

req.cookies is an object, from the express docs:

When using cookie-parser middleware, this property is an object that contains cookies sent by the request. If the request contains no cookies, it defaults to {}.

So you need to set the jwt inside the cookie in this way:

.set('Cookie', `jwtToken=${token}`)

And get it in your middleware:

const { jwtToken } = req.cookies;
jwt.verify(jwtToken, ...

Upvotes: 1

Related Questions