How can you use cookies with superagent?
Asked Answered
A

6

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?

Ashburn answered 12/8, 2012 at 4:28 Comment(0)
G
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.

Gonorrhea answered 4/10, 2012 at 20:4 Comment(3)
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.Engineer
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.Pastor
this did not work / if it did it isn't really sufficient... can someone provide an example of how that works....Scyphate
A
22

Seems like following code works fine;

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

Aftersensation answered 14/1, 2016 at 16:55 Comment(1)
This did not work for me using Django {"Cookie": "csrftoken=token here"}Sidsida
E
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) { })
Exhibitionist answered 28/9, 2016 at 10:5 Comment(0)
F
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')
Ferromagnetic answered 6/7, 2016 at 21:28 Comment(0)
O
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();
});
Oversubtle answered 2/5, 2020 at 2:13 Comment(1)
Shouldn't it be res.header['set-cookie'] rather than res.headers['set-cookie']?Carefree
H
1

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"))

  
Hwang answered 28/2, 2022 at 2:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.