40

I'm doing cookie session management with express with something like this:

req.session.authentication = auth; 

And I verify the authenticated urls with something like

if(!req.session.authentication){res.send(401);} 

Now I'm building tests for the URLs with mocha, superagent and should, however I can't seem to find a way to get/set the cookie with superagent. I even tried to request the login before the authenticated test but it is not working,

I have tried adding the request to the login in the before statement for the mocha BDD suite, however it is still telling me that the request is unauthorized, I have tested the authentication doing the requests from the browser, however it is not working from the suite any ideas why?

6 Answers 6

35

Use superagent.agent() (instead of plain old superagent) to make requests have persistent cookies. See 'Saving cookies' in the superagent docs, or the code examples: agency.js, controller.test.js.

Sign up to request clarification or add additional context in comments.

3 Comments

Note that superagent.agent() has serious, undocumented issues in how it handles cookies for most request definitions - anything more complicated than a get(url,opts,cb) requires hooking into undocumented private methods.
In fact the documentation has no mention of cookies either. I was really starting to like this library and had high hopes because of the author, but it turns out to be useless if you want to use a session cookie.
this did not work / if it did it isn't really sufficient... can someone provide an example of how that works....
23

Seems like following code works fine;

req.set('Cookie', "cookieName1=cookieValue1;cookieName2=cookieValue2");

1 Comment

This did not work for me using Django {"Cookie": "csrftoken=token here"}
10

If the issue is in sending cookies for CORS requests use .withCredentials() method described here

request .get('http://localhost:4001/') .withCredentials() .end(function(err, res) { }) 

Comments

5

Since you mentioned you need to both get and set the cookie:

Get:

const request = await Superagent.get('...') const cookie = request.header['set-cookie'] 

Set:

Superagent.post('...').set('Cookie', 'cookie_info') 

Comments

3

2020 +

A clean way to do it is:

  • create a simple cookie store
  • abstract set Cookie to send it in each request
  • update the cookie only when needed

Note I keep the same URL because I use graphql but you can make it a parameter:

const graph = agent => agent.post('/graph') .set('cookie', cookieStore.get()); const handleCookie = res => cookieStore.set(res.headers['set-cookie'][0]); let currentCookie=""; const cookieStore = { set: cookie=>{currentCookie=cookie}, get: cookie=>currentCookie, }; module.exports = {graph,connectTestUser,handleCookieResponse}; 

You can now just use graph(agent) to send a request and handleCookie(response) when you have a response that may update your cookie (set or clear), example:

graph(agent).end((err,res) => { if (err) return done(err); res.statusCode.should.equal(200); handleCookie(res); return done(); }); 

1 Comment

Shouldn't it be res.header['set-cookie'] rather than res.headers['set-cookie']?
2

Add a cookie to agent cookiejar:

const request = require('superagent'); const {Cookie} = require('cookiejar') const agent = request.agent() agent.jar.setCookie(new Cookie("foo=bar")) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.