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.

What problem does this feature solve?

Handle cookie jar in order to automatically resend received cookies on every subsequent request (server-side). Actually, axios doesn’t resend cookie received (with set-cookie) by nuxt serverResponse (in a serverMiddleware for example). It cause many problem in my nuxt app.

I have to do something like this (temporary fix) :

$axios.onResponse((resp) => {
        if(resp.headers['set-cookie'] && process.server){
            try{
                // add header to nuxt's server response
                res.setHeader('Set-Cookie', [ ...resp.headers['set-cookie'] ])
            }catch(e) {}
        }
        return resp
    })

but in some case, set-cookie header is duplicated…

<div align="right">This feature request is available on Nuxt community (#c329)</div>

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:4
  • Comments:28 (6 by maintainers)

github_iconTop GitHub Comments

18reactions
SebastiaanYNcommented, May 2, 2020

It’s not cookies …

You’re right, ignore that.

I think I managed to get a working plugin that updates cookies for Axios, and merges them on the response object. This allows sequential requests to have the correct cookies.

// plugins/ssr-cookie-proxy.js
import { parse as parseCookie } from 'cookie';

function parseSetCookies(cookies) {
  return cookies
    .map(cookie => cookie.split(';')[0])
    .reduce((obj, cookie) => ({
      ...obj,
      ...parseCookie(cookie),
    }), {});
}

function serializeCookies(cookies) {
  return Object
    .entries(cookies)
    .map(([name, value]) => `${name}=${encodeURIComponent(value)}`)
    .join('; ');
}

function mergeSetCookies(oldCookies, newCookies) {
  const cookies = new Map();

  function add(setCookie) {
    const cookie = setCookie.split(';')[0];
    const name = Object.keys(parseCookie(cookie))[0];

    cookies.set(name, cookie);
  }

  oldCookies.forEach(add);
  newCookies.forEach(add);

  return [...cookies.values()];
}

export default function ({ $axios, res }) {
  $axios.onResponse((response) => {
    const setCookies = response.headers['set-cookie'];

    if (setCookies) {
      // Combine the cookies set on axios with the new cookies and serialize them
      const cookie = serializeCookies({
        ...parseCookie($axios.defaults.headers.common.cookie),
        ...parseSetCookies(setCookies),
      });

      $axios.defaults.headers.common.cookie = cookie; // eslint-disable-line no-param-reassign

      // If the res already has a Set-Cookie header it should be merged
      if (res.getHeader('Set-Cookie')) {
        const newCookies = mergeSetCookies(
          res.getHeader('Set-Cookie'),
          setCookies,
        );

        res.setHeader('Set-Cookie', newCookies);
      } else {
        res.setHeader('Set-Cookie', setCookies);
      }
    }
  });
}

And then register it in nuxt.config.js

plugins: [
  { src: '@/plugins/ssr-cookie-proxy.js', mode: 'server' },
],
2reactions
SebastiaanYNcommented, May 2, 2020

I’m currently dealing with the same problem. My backend adds a Set-Cookie header to the response with a new access_token whenever it has expired. This causes issues with SSR because they aren’t forwarded to the client.

I’ve been working around this issue so far by making requests that require authentication from the client, but this takes away the smoothness of SSR.

An issue with the solution provided above is that on subsequent requests Axios might also need to access the new cookies. The ideal solution would be to mimic the behavior of browsers when dealing with cookies.

A possible solution I’ve been considering is to have a server-side plugin that updates the Axios cookies, and the Set-Cookie header on the response, whenever a Set-Cookie header is received.

export default function ({ $axios, res }) {
  $axios.onResponse((response) => {
    // get the set-cookie header from the response
    const setCookies = response.headers['set-cookie'];

    if (setCookies) {
      // parse the cookies axios uses
      const cookies = parse($axios.defaults.headers.common.cookie);

      // add cookies from setCookies to cookies
      // set $axios.defaults.headers.common.cookie equal to the new cookie header

      // merge the existing Set-Cookie header with setCookies
      // set the cookies on the response, so the client gets them back
      res.setHeader('Set-Cookie', setCookies);
    }
  });
}

One possible issue with this solution is that it would proxy all cookies. So a potential filter could be added to not proxy cookies such as x-powered-by, x-ratelimit-limit, x-ratelimit-remaining, and others.

It would be nice to have this as an option, so SSR can be used to the fullest, without worrying about cookies not syncing.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cookies Overview and HTTP Proxies - Computer Science
What is a Cookie? ▫ Small piece of data generated by a web server, stored on the client's hard drive. ▫ Serves as...
Read more >
How to Allow Cookies on a Proxy - Small Business - Chron.com
1. Open one of the cookie-optional proxy Web applications in a Web browser (see Resources). · 2. Type the URL to your blocked...
Read more >
Cookie Proxies
Cookie Proxies Sells High Quality Residential Proxies & The Fastest Data Center Proxies. Multiple Data Center Locations Such As Ashburn, Chicago, ...
Read more >
Cookie? Proxy? Cache? #1 - Yuta Fujii - Medium
Even if you are not familiar with IT, most of you have ever heard about cookie, proxy, cache. For example: “Remove cookies and...
Read more >
Is it permissible for an intermediate proxy to add cookies ...
RFC 2965 HTTP State Management Mechanism, 3.5 Caching Proxy Role it says: Proxies MUST NOT introduce Set-Cookie2 (Cookie) headers of their own ...
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