T
TanStack6d ago
old-apricot

Example of how to forward cookies from client

I am using an external API that creates a session cookie with httpOnly after logging in. How can I forward this cookie from the browser so that I can use it for datafetching?
8 Replies
environmental-rose
environmental-rose6d ago
more details please. who calls what when etc
old-apricot
old-apricotOP6d ago
Ok so my login flow is the following: 1. Login anchor tag that points to backend service http://localhost:4013/api/auth/login. This takes the user through OAuth process, creates a session, sets a httpOnly cookie, and then redirects the user back to the tanstack-start app. 2. In the tanstack start app I have an openapi-fetch fully typed client that sends fetch requests to localhost:4013. For an SPA or client-side requests that go directly to localhost:4013 this just works with credentials: 'include' I've tried creating a middleware that creates the openapi-fetch client and puts it in the context, and then create an api-route that does the fetch to localhost:4013, but then I have to call the tanstack-start api route and I lose the types and it feels like a lot of double work. Am I overthinking this or is maybe start not the right choice here Is there a way to get the Request so I can extract the headers from a server function?
old-apricot
old-apricotOP6d ago
There's a mention of getRequest here but there's no more information and I can't find out where to import it from
Server Functions | TanStack Start React Docs
What are Server Functions? Server functions let you define server-only logic that can be called from anywhere in your application loaders, components, hooks, or other server functions. They run on the...
old-apricot
old-apricotOP6d ago
https://github.com/TanStack/router/issues/2184#issuecomment-2499245920 This is a good example of what I'm trying to achieve
GitHub
[Start]: accessing header inside beforeLoad throw error on the cl...
Describe the bug So I'm trying to load the cookies on the server, and pass them to the component using useRouteContext. but it throw an error Module "node:async_hooks" has been extern...
old-apricot
old-apricotOP6d ago
const cookieMiddleware: Middleware = {
onRequest({ request }) {
if (isServer) {
const serverCookie = getRequestHeader("Cookie") ?? "";
request.headers.set("Cookie", serverCookie);
}

return request;
},
};

export const api =
createClient<paths>({
baseUrl,
credentials: "include",
});

api.use(cookieMiddleware);
const cookieMiddleware: Middleware = {
onRequest({ request }) {
if (isServer) {
const serverCookie = getRequestHeader("Cookie") ?? "";
request.headers.set("Cookie", serverCookie);
}

return request;
},
};

export const api =
createClient<paths>({
baseUrl,
credentials: "include",
});

api.use(cookieMiddleware);
I guess it would be something like this, but I'm not sure I can call getRequestHeader from inside there and I don't know how to check if I'm on the server or not
continuing-cyan
continuing-cyan6d ago
i believe if you wrap cookieMiddleware in a createServerFn you should be able to call the getRequest/getCookie safely in it. if you are making request from the browser this should be fine, but any request originating from the server wouldn't have the cookie set
old-apricot
old-apricotOP6d ago
Thanks for the tip! I made an isomorphic function like this instead:
const getCookieMiddleware = createIsomorphicFn()
.server(() => {
const middleware: Middleware = {
onRequest({ request }) {
const serverCookie = getRequestHeader("Cookie") ?? "";
request.headers.set("Cookie", serverCookie);
return request;
},
};

return middleware;
})
.client(() => {
const middleware: Middleware = {
onRequest({ request }) {
return request;
},
};
return middleware;
});

export const api = createClient<paths>({
baseUrl,
credentials: "include",
});

api.use(getCookieMiddleware());
const getCookieMiddleware = createIsomorphicFn()
.server(() => {
const middleware: Middleware = {
onRequest({ request }) {
const serverCookie = getRequestHeader("Cookie") ?? "";
request.headers.set("Cookie", serverCookie);
return request;
},
};

return middleware;
})
.client(() => {
const middleware: Middleware = {
onRequest({ request }) {
return request;
},
};
return middleware;
});

export const api = createClient<paths>({
baseUrl,
credentials: "include",
});

api.use(getCookieMiddleware());
environmental-rose
environmental-rose6d ago
yes thats a good solution

Did you find this page helpful?