Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws-lambda preset should use cookies vs set-cookie header in response #245

Closed
brtinney opened this issue May 16, 2022 · 0 comments · Fixed by #357
Closed

aws-lambda preset should use cookies vs set-cookie header in response #245

brtinney opened this issue May 16, 2022 · 0 comments · Fixed by #357
Assignees
Labels
bug Something isn't working

Comments

@brtinney
Copy link

Environment

aws-lambda deployment setting

nitro via nuxt@3.0.0-rc3

Reproduction

See below

Describe the bug

It's not possible to pass multiple cookies with the set-cookie header via AWS Lambda, so the normalizeOutgoingHeaders does not help with cookies in responses.

const handler = async function handler2(event, context) {
  const url = withQuery(event.path || event.rawPath, event.queryStringParameters || {});
  const method = event.httpMethod || event.requestContext?.http?.method || "get";
  if ("cookies" in event && event.cookies) {
    event.headers.cookie = event.cookies.join(",");
  }
  const r = await nitroApp.localCall({
    event,
    url,
    context,
    headers: normalizeIncomingHeaders(event.headers),
    method,
    query: event.queryStringParameters,
    body: event.body
  });
  return {
    statusCode: r.status,
    headers: normalizeOutgoingHeaders(r.headers),
    body: r.body.toString()
  };
};
function normalizeIncomingHeaders(headers) {
  return Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value]));
}
function normalizeOutgoingHeaders(headers) {
  return Object.fromEntries(Object.entries(headers).map(([k, v]) => [k, Array.isArray(v) ? v.join(",") : v]));
}

This results in issues like the following for some requests (e.g. adapted @auth0/nextjs code for SSR-compatible serverless auth), as only the first cookie is actually set:

{"url":"/api/auth/callback?code=xxx&state=yyy","statusCode":400,"statusMessage":"checks.state argument is missing","message":"checks.state argument is missing","description":""}

Additional context

Documentation here: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.v2

I was able to fix the issue with this hack to the handler, which is very inelegant:

const handler = async function handler2(event, context) {
  const url = withQuery(event.path || event.rawPath, event.queryStringParameters || {});
  const method = event.httpMethod || event.requestContext?.http?.method || "get";
  if ("cookies" in event && event.cookies) {
    event.headers.cookie = event.cookies.join("; ");
  }
  const r = await nitroApp.localCall({
    event,
    url,
    context,
    headers: normalizeIncomingHeaders(event.headers),
    method,
    query: event.queryStringParameters,
    body: event.body
  });
  const headers = normalizeOutgoingHeaders(r.headers);
  return Object.assign({
    statusCode: r.status,
    body: r.body.toString()
  }, headers);
};
function normalizeIncomingHeaders(headers) {
  return Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value]));
}
function normalizeOutgoingHeaders(headers) {
  const obj = {
    headers: {},
    cookies: []
  };
  for (const k in headers) {
    const v = headers[k];
    if (k.toLowerCase() === 'set-cookie') {
      if (Array.isArray(v)) {
        obj.cookies = obj.cookies.concat(v);
      } else {
        obj.cookies = obj.cookies.concat(v.split(','));
      }
    } else {
      obj.headers[k] = v;
    }
  }
  return obj;
}

Note that I also changed the .join() to use ; because the cookie packages expects that format.

Apologies if this should be on nuxt/framework instead. This took me many hours to find out, and I just wanted to make sure it was documented somewhere to eventually get fixed, so that my hack is no longer required as a post-build step.

Logs

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants