Replies: 7 comments 7 replies
-
Hey there 👋 I am currently implementing server-side authentication with Supabase and have run into this issue. Challange
Using the default // decodeCookieValue
async function decodeCookieValue(unsign, value, secrets) {
if (secrets.length > 0) {
for (let secret of secrets) {
let unsignedValue = await unsign(value, secret);
if (unsignedValue !== false) {
return decodeData(unsignedValue);
}
}
return null;
}
return decodeData(value);
} Current solutionI implemented my own // create-foreign-cookie.server.ts
import type { CookieParseOptions, CookieSerializeOptions } from "cookie";
import { parse, serialize } from "cookie";
import type { CreateCookieFunction } from "@remix-run/server-runtime";
export type { CookieParseOptions, CookieSerializeOptions };
/**
* Creates a logical container for managing a browser cookie from the server.
*
* @see https://remix.run/api/remix#createcookie
*/
function createCookieFactory(): CreateCookieFunction {
return (name, cookieOptions = {}) => {
const { secrets, ...options } = {
secrets: [],
path: "/",
...cookieOptions,
};
return {
get name() {
return name;
},
get isSigned() {
return secrets.length > 0;
},
get expires() {
// Max-Age takes precedence over Expires
return typeof options.maxAge !== "undefined"
? new Date(Date.now() + options.maxAge * 1000)
: options.expires;
},
async parse(cookieHeader, parseOptions) {
if (!cookieHeader) return null;
let cookies = parse(cookieHeader, { ...options, ...parseOptions });
return name in cookies ? (cookies[name] === "" ? "" : cookies[name]) : null;
},
async serialize(value, serializeOptions) {
return serialize(name, value, {
...options,
...serializeOptions,
});
},
};
};
}
const createForeignCookie = createCookieFactory();
export default createForeignCookie; // cookies.server.ts
import createForeignCookie from "~/lib/create-foreign-cookie.server";
export const sbRefreshTokenCookie = createForeignCookie("sb-refresh-token"); |
Beta Was this translation helpful? Give feedback.
-
Converting this to a Proposal discussion, as per our Development Process. |
Beta Was this translation helpful? Give feedback.
-
This just bit me. I was trying to read a cookie set by another application in Remix and It would have saved me a lot of trouble if this was documented here: https://remix.run/docs/en/main/utils/cookies |
Beta Was this translation helpful? Give feedback.
-
Also ran into this. We're setting a language cookie like: |
Beta Was this translation helpful? Give feedback.
-
You can just: const headers = new Headers();
headers.append('Set-Cookie', 'language=en');
return json({text: 'some data'}, {
headers
}) |
Beta Was this translation helpful? Give feedback.
-
I ran into this earlier this week. We've been using the Remix created cookies with the front-end code without any issues, so it took me a while to suspect I think it's unseasonable to assume all cookies should be base64 encoded JSON strings. Either way, it would have been helpful if the documentation had clearly spelled out this implementation choice. |
Beta Was this translation helpful? Give feedback.
-
Is there any Remix solution to this so far, besides using the commented utility ( |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
At present, the cookie utilities always encode (and expect to decode) a base64, JSON value, using the encodeCookieValue/decodeCookieValue functions. This is fine when the cookie is only being read in Remix loaders, actions, etc. If you wish to interact with the outside world it becomes a problem for a couple of reasons:
parse
method of a Remix cookie. For example, if you are on a subdomain and want to read a cookie set at the domain root.HttpOnly
cookie to be read in JavaScript client side, or by some other system (say, a load balancer).It would be helpful if I could read/write both cookies created by Remix, and "raw" cookies using the same interface. The underlying
cookie
interface takes anencode
/decode
function in the options of theserialize
/parse
methods. This would help follow the advice from the docs to put all your cookies in aapp/cookie.js
file.My first thought is that Remix could, by default, not do anything extra to the cookie and add an extra helper
createJsonCookie
which prebakes thebtoa(JSON.stringify(x))
/JSON.parse(atob(x))
encode
/decode
functions. (And maybe changes the options toOmit<CookieSerializeOptions, 'encode'>
/Omit< CookieParseOptions, 'decode'>
.) This would also prevent the (potentially) surprising behaviour if a user were to specifyencode
/decode
themselves where the value passed to these functions would already have been modified.Beta Was this translation helpful? Give feedback.
All reactions