Replies: 6 comments 6 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.
-
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