question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

wrong behavie when there are same keys in responseInit.headers

See original GitHub issue

I use koajs/session for auth.

There should be “set-cookie”: [“koa:sess=xxx;…”, “koa:sess.sig=xxx;…”] in the response header, not “set-cookie”: “koa:sess=xxx;…, koa:sess.sig=xxx;…” .

And of course the auth doesn’t work.

After digging into the code , I think this line in runHttpQuery.ts should be for (const [name, value] of Object.entries(response.http.headers.raw())) {

Am I right ? Sorry for my poor english…

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

7reactions
kgoggincommented, Feb 24, 2020

I bumped into this, too. Just to clarify the use case, when using cookie-based auth it’s common to set two cookies to mitigate against CSRF attacks (known as the double-submit cookie pattern). I do think this would be a good thing for Apollo Server to eventually support, but I fear that doing so would be a breaking change.

As @yurist38 pointed out, Apollo Server is leaning on node-fetch’s Headers class which doesn’t allow for setting the same header key more than once (which would appear to be against the official fetch standard which specifically mentions:

A header list is essentially a specialized multimap. An ordered list of key-value pairs with potentially duplicate keys.

Furthermore the Header class appears to stringify any value passed to set, such that ["foo", "bar"] will turn into "foo, bar". So, not only can we not call set twice with the same key, we can’t pass something more complicated to set.

I’m running apollo-server-lambda, and Lambda has an API for setting multi-value headers via the mutliValueHeaders key in the response object. So, my current work-around is to:

  1. Stringify an array of cookie values (using JSON.stringify so that I can parse it back out again)
  2. Proxy the Apollo handler to check the value for set-cookie and parse it back into an array, and then set mutltiValueHeaders instead of plain headers.

Here’s what that looks like for anyone curious:

const handleManyCookies = (headers = {}) => {
  if (headers["set-cookie"]) {
    try {
      const value = JSON.parse(headers["set-cookie"]);
      if (Array.isArray(value)) {
        return {
          multiValueHeaders: {
            ...headers,
            "set-cookie": value,
          },
        };
      }
    } catch (err) {
      return { headers };
    }
  }

  return { headers };
};

const proxiedHandler = (event, context, cb) => {
  const apolloHandler = server.createHandler({
    cors: {
      origin: "*",
      credentials: true,
    },
  });

  return apolloHandler(event, context, (err, response = {}) => {
    if (err) {
      cb(err);
    } else {
      const { headers, ...responseData } = response;
      const newHeaders = handleManyCookies(headers);

      cb(null, {
        ...responseData,
        ...newHeaders,
      });
    }
  });
};

I’d be wary of suggesting a way to address all of this in apollo-server because it feels like a pretty substantial change would be needed to the underlying way it handles headers. Even if node-fetch released support for multi-value headers tomorrow, there’d still need to be changes made in this library for correctly parsing that API change and applying it correctly to the various server plugins. To me, this feels like something the core team needs to decide if it wants to support (IMHO, it really ought to) and then come up with an approach that isn’t dependent on node-fetch (an Apollo-specific headers implementation).

Hope all this is helpful both to anyone else who lands here looking for a way around this, and to the core team in deciding how to move forward with this issue.

2reactions
yurist38commented, Nov 19, 2019

Any updates on this one? I clearly see that it’s not possible to send multiple cookies now, faced this issue in my project too. Please take a look at the problem! Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

How return error message in spring mvc @Controller
As Sotirios Delimanolis already pointed out in the comments, there are two options: Return ResponseEntity with error message.
Read more >
Same path: When a header is in the request mapping ... - GitHub
The expected behavior it`s to ignore or merge both data sources (request mapping and method parameter).
Read more >
How to Read HTTP Headers in Spring REST Controllers
If a header named accept-language isn't found in the request, the method returns a “400 Bad Request” error. Our headers don't have to...
Read more >
Error handling for a Spring-based REST API - Microflash
Spring Boot provides pretty nifty defaults to handle exceptions and formulate a helpful response in case anything goes wrong.
Read more >
HTTP Request and Response Headers in a Spring Boot ...
Learn how to read headers from an HTTP Request and write them to an HTTP Response.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found