[GH-ISSUE #1136] Hono RPC Cookies are not attaching to the request #8610

Closed
opened 2026-04-13 03:44:02 -05:00 by GiteaMirror · 3 comments
Owner

Originally created by @Vijayabaskar56 on GitHub (Jan 4, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/1136

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Backend With Hono
  2. Frontend with React , React Query and Hono RPC
  3. only auth request getting the cookies details not the once that I send with my hono rpc setup

Current vs. Expected behavior

Here my Logs

Server running on http://localhost:3000
<-- GET /api/auth/get-session
Headers {
"host": "localhost:3000",
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
"accept": "/",
"accept-language": "en-US,en;q=0.5",
"accept-encoding": "gzip, deflate, br, zstd",
"referer": "http://localhost:5173/",
"origin": "http://localhost:5173",
"dnt": "1",
"connection": "keep-alive",
"cookie": "__Secure-trade-it.session_token=SacxP8ZRB2DhWjeiwaEK-C1rCrga9UIY.okvG6HQdTGr2KRs
0qmrsFM3%2BsDp6dOcoH4Rrb69s2mA%3D",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-gpc": "1",
"sec-fetch-site": "same-site",
"priority": "u=4",
} session
--> GET /api/auth/get-session 200 1s
<-- GET /api/test
Headers {
"host": "localhost:3000",
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
"accept": "/",
"accept-language": "en-US,en;q=0.5",
"accept-encoding": "gzip, deflate, br, zstd",
"referer": "http://localhost:5173/",
"content-type": "application/json",
"origin": "http://localhost:5173",
"dnt": "1",
"connection": "keep-alive",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-gpc": "1",
"sec-fetch-site": "same-site",
"priority": "u=4",
} session
--> GET /api/test 200 1ms
<-- GET /api/auth/get-session
Headers {
"host": "localhost:3000",
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
"accept": "/",
"accept-language": "en-US,en;q=0.5",
"accept-encoding": "gzip, deflate, br, zstd",
"referer": "http://localhost:5173/",
"origin": "http://localhost:5173",
"dnt": "1",
"connection": "keep-alive",
"cookie": "__Secure-trade-it.session_token=SacxP8ZRB2DhWjeiwaEK-C1rCrga9UIY.okvG6HQdTGr2KRs0qmrsFM3%2BsDp6dOcoH4Rrb69s2mA%3D",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-gpc": "1",
"sec-fetch-site": "same-site",
"priority": "u=4",
} session
--> GET /api/auth/get-session 200 365ms

Here as you can see , only for the auth related request the cookies was attaching, and not for other router , now I wanted cookies to be atttached to my other request as well , so that , I can use the hono middleware to set user and session details in my hono context

https://www.better-auth.com/docs/integrations/hono#middleware

is there anything that am I missing in my config or any other work arounds ?
greatly appreated additional details on how to set cookies for specify request and it's wins and loses

What version of Better Auth are you using?

1.0.21

Provide environment information

- OS: [Arch Linux]
- Browser : [zen-brower, chrome]

Which area(s) are affected? (Select all that apply)

Backend, Client

Auth config (if applicable)

this is the my auth config in the backend

import { betterAuth } from "better-auth";
import { mongodbAdapter } from "better-auth/adapters/mongodb";
import { MongoClient } from "mongodb";
import { customSession, emailOTP, passkey, phoneNumber, twoFactor, username } from "better-auth/plugins";
import { config } from "./envConfig";
import { sendEmail } from "./sendEmail";
const client = new MongoClient(config.CONNECTION_URL);
import { admin } from "better-auth/plugins";
import { emailHarmony } from "better-auth-harmony";
import redis from "./redis";
import { userService } from "../services/user.service";

const db = client.db();
export const auth = betterAuth({
 database: mongodbAdapter(db),
 appName: "Trade It",
 emailAndPassword: {
  enabled: true,
  sendResetPassword: async ({ user, url, token }, request) => {
   await sendEmail({
    to: user.email,
    subject: "Reset your password",
    body: `Click the link to reset your password: ${url}`,
   });
  },
 },
 crossSubDomainCookies: {
  enabled: true,
 },
 socialProviders: {
  google: {
   clientId: config.GOOGLE_CLIENT_ID as string,
   clientSecret: config.GOOGLE_CLIENT_SECRET as string,
  },
 },
 logger: {
  enabled: true,
  level: "debug",
  log: console.log,
 },
 plugins: [
  customSession(async ({ user, session }) => {
   const userData = await userService.findById(session.userId);
   return {
    user: {
     ...user,
     language: userData?.language,
     currency: userData?.currency,
    },
    session
   };
  }),
  emailOTP({
   async sendVerificationOTP({ email, otp, type }) {
    console.log("Sending OTP to", email, otp);
    await sendEmail({ body: `Your OTP is ${otp} for ${type}`, subject: "Sign Up OTP", to: email });
   },
  }),
  twoFactor({
   issuer: "Trade It",
   totpOptions: {
    digits: 6,
   },
  }),
  username(),
  admin(),
  emailHarmony(),
  passkey(),
 ],
 advanced: {
  cookiePrefix: "trade-it",
  crossSubDomainCookies: {
   enabled: true
  },
  useSecureCookies: true,
 },
 rateLimit: {
  window: 10, // time window in seconds
  max: 30, // max requests in the window
 },
 trustedOrigins: ["http://localhost:5173",],
});



### Additional context

Both client and server running Seperately on different port

Detailed logs

Server running on http://localhost:3000
<-- GET /api/auth/get-session
Headers {
"host": "localhost:3000",
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
"accept": "/",
"accept-language": "en-US,en;q=0.5",
"accept-encoding": "gzip, deflate, br, zstd",
"referer": "http://localhost:5173/",
"origin": "http://localhost:5173",
"dnt": "1",
"connection": "keep-alive",
"cookie": "__Secure-trade-it.session_token=SacxP8ZRB2DhWjeiwaEK-C1rCrga9UIY.okvG6HQdTGr2KRs
0qmrsFM3%2BsDp6dOcoH4Rrb69s2mA%3D",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-gpc": "1",
"sec-fetch-site": "same-site",
"priority": "u=4",
} session
--> GET /api/auth/get-session 200 1s
<-- GET /api/test
Headers {
"host": "localhost:3000",
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
"accept": "/",
"accept-language": "en-US,en;q=0.5",
"accept-encoding": "gzip, deflate, br, zstd",
"referer": "http://localhost:5173/",
"content-type": "application/json",
"origin": "http://localhost:5173",
"dnt": "1",
"connection": "keep-alive",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-gpc": "1",
"sec-fetch-site": "same-site",
"priority": "u=4",
} session
--> GET /api/test 200 1ms
<-- GET /api/auth/get-session
Headers {
"host": "localhost:3000",
"user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0",
"accept": "/",
"accept-language": "en-US,en;q=0.5",
"accept-encoding": "gzip, deflate, br, zstd",
"referer": "http://localhost:5173/",
"origin": "http://localhost:5173",
"dnt": "1",
"connection": "keep-alive",
"cookie": "__Secure-trade-it.session_token=SacxP8ZRB2DhWjeiwaEK-C1rCrga9UIY.okvG6HQdTGr2KRs0qmrsFM3%2BsDp6dOcoH4Rrb69s2mA%3D",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-gpc": "1",
"sec-fetch-site": "same-site",
"priority": "u=4",
} session
--> GET /api/auth/get-session 200 365ms

Originally created by @Vijayabaskar56 on GitHub (Jan 4, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/1136 ### Is this suited for github? - [X] Yes, this is suited for github ### To Reproduce 1. Backend With Hono 2. Frontend with React , React Query and Hono RPC 3. only auth request getting the cookies details not the once that I send with my hono rpc setup ### Current vs. Expected behavior Here my Logs Server running on http://localhost:3000 <-- GET /api/auth/get-session Headers { "host": "localhost:3000", "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0", "accept": "*/*", "accept-language": "en-US,en;q=0.5", "accept-encoding": "gzip, deflate, br, zstd", "referer": "http://localhost:5173/", "origin": "http://localhost:5173", "dnt": "1", "connection": "keep-alive", "cookie": "__Secure-trade-it.session_token=SacxP8ZRB2DhWjeiwaEK-C1rCrga9UIY.okvG6HQdTGr2KRs 0qmrsFM3%2BsDp6dOcoH4Rrb69s2mA%3D", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-gpc": "1", "sec-fetch-site": "same-site", "priority": "u=4", } session --> GET /api/auth/get-session 200 1s <-- GET /api/test Headers { "host": "localhost:3000", "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0", "accept": "*/*", "accept-language": "en-US,en;q=0.5", "accept-encoding": "gzip, deflate, br, zstd", "referer": "http://localhost:5173/", "content-type": "application/json", "origin": "http://localhost:5173", "dnt": "1", "connection": "keep-alive", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-gpc": "1", "sec-fetch-site": "same-site", "priority": "u=4", } session --> GET /api/test 200 1ms <-- GET /api/auth/get-session Headers { "host": "localhost:3000", "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0", "accept": "*/*", "accept-language": "en-US,en;q=0.5", "accept-encoding": "gzip, deflate, br, zstd", "referer": "http://localhost:5173/", "origin": "http://localhost:5173", "dnt": "1", "connection": "keep-alive", "cookie": "__Secure-trade-it.session_token=SacxP8ZRB2DhWjeiwaEK-C1rCrga9UIY.okvG6HQdTGr2KRs0qmrsFM3%2BsDp6dOcoH4Rrb69s2mA%3D", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-gpc": "1", "sec-fetch-site": "same-site", "priority": "u=4", } session --> GET /api/auth/get-session 200 365ms Here as you can see , only for the auth related request the cookies was attaching, and not for other router , now I wanted cookies to be atttached to my other request as well , so that , I can use the hono middleware to set user and session details in my hono context https://www.better-auth.com/docs/integrations/hono#middleware is there anything that am I missing in my config or any other work arounds ? greatly appreated additional details on how to set cookies for specify request and it's wins and loses ### What version of Better Auth are you using? 1.0.21 ### Provide environment information ```bash - OS: [Arch Linux] - Browser : [zen-brower, chrome] ``` ### Which area(s) are affected? (Select all that apply) Backend, Client ### Auth config (if applicable) ```typescript this is the my auth config in the backend import { betterAuth } from "better-auth"; import { mongodbAdapter } from "better-auth/adapters/mongodb"; import { MongoClient } from "mongodb"; import { customSession, emailOTP, passkey, phoneNumber, twoFactor, username } from "better-auth/plugins"; import { config } from "./envConfig"; import { sendEmail } from "./sendEmail"; const client = new MongoClient(config.CONNECTION_URL); import { admin } from "better-auth/plugins"; import { emailHarmony } from "better-auth-harmony"; import redis from "./redis"; import { userService } from "../services/user.service"; const db = client.db(); export const auth = betterAuth({ database: mongodbAdapter(db), appName: "Trade It", emailAndPassword: { enabled: true, sendResetPassword: async ({ user, url, token }, request) => { await sendEmail({ to: user.email, subject: "Reset your password", body: `Click the link to reset your password: ${url}`, }); }, }, crossSubDomainCookies: { enabled: true, }, socialProviders: { google: { clientId: config.GOOGLE_CLIENT_ID as string, clientSecret: config.GOOGLE_CLIENT_SECRET as string, }, }, logger: { enabled: true, level: "debug", log: console.log, }, plugins: [ customSession(async ({ user, session }) => { const userData = await userService.findById(session.userId); return { user: { ...user, language: userData?.language, currency: userData?.currency, }, session }; }), emailOTP({ async sendVerificationOTP({ email, otp, type }) { console.log("Sending OTP to", email, otp); await sendEmail({ body: `Your OTP is ${otp} for ${type}`, subject: "Sign Up OTP", to: email }); }, }), twoFactor({ issuer: "Trade It", totpOptions: { digits: 6, }, }), username(), admin(), emailHarmony(), passkey(), ], advanced: { cookiePrefix: "trade-it", crossSubDomainCookies: { enabled: true }, useSecureCookies: true, }, rateLimit: { window: 10, // time window in seconds max: 30, // max requests in the window }, trustedOrigins: ["http://localhost:5173",], }); ``` ``` ### Additional context Both client and server running Seperately on different port Detailed logs ``` Server running on http://localhost:3000 <-- GET /api/auth/get-session Headers { "host": "localhost:3000", "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0", "accept": "*/*", "accept-language": "en-US,en;q=0.5", "accept-encoding": "gzip, deflate, br, zstd", "referer": "http://localhost:5173/", "origin": "http://localhost:5173", "dnt": "1", "connection": "keep-alive", "cookie": "__Secure-trade-it.session_token=SacxP8ZRB2DhWjeiwaEK-C1rCrga9UIY.okvG6HQdTGr2KRs 0qmrsFM3%2BsDp6dOcoH4Rrb69s2mA%3D", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-gpc": "1", "sec-fetch-site": "same-site", "priority": "u=4", } session --> GET /api/auth/get-session 200 1s <-- GET /api/test Headers { "host": "localhost:3000", "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0", "accept": "*/*", "accept-language": "en-US,en;q=0.5", "accept-encoding": "gzip, deflate, br, zstd", "referer": "http://localhost:5173/", "content-type": "application/json", "origin": "http://localhost:5173", "dnt": "1", "connection": "keep-alive", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-gpc": "1", "sec-fetch-site": "same-site", "priority": "u=4", } session --> GET /api/test 200 1ms <-- GET /api/auth/get-session Headers { "host": "localhost:3000", "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0", "accept": "*/*", "accept-language": "en-US,en;q=0.5", "accept-encoding": "gzip, deflate, br, zstd", "referer": "http://localhost:5173/", "origin": "http://localhost:5173", "dnt": "1", "connection": "keep-alive", "cookie": "__Secure-trade-it.session_token=SacxP8ZRB2DhWjeiwaEK-C1rCrga9UIY.okvG6HQdTGr2KRs0qmrsFM3%2BsDp6dOcoH4Rrb69s2mA%3D", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-gpc": "1", "sec-fetch-site": "same-site", "priority": "u=4", } session --> GET /api/auth/get-session 200 365ms ```
GiteaMirror added the lockedbug labels 2026-04-13 03:44:02 -05:00
Author
Owner

@Vijayabaskar56 commented on GitHub (Jan 8, 2025):

import Cookies from 'js-cookie';
export const client = hc<ApiRoutes>("http://localhost:3000/", {
});
export const api = client.api;
export async function test() {
 const res = await api.test.$get();
 if (!res.ok) {
  throw new Error("server error");
 }
 const data = await res.json();
 return data;
};

export async function testFetch() {
 const res = await betterFetch('http://localhost:3000/api/test');
 console.log('cookie', getCookies({}).sessionData, Cookies.get());
 if (!res.error) {
  throw new Error("server error");
 }
 const data = await res.data;
 return data;
}

Any help on my issue would be appreciated, I have cannot get the cookie with js-cookies, and I cannot set cokies to the hono rpc client, even when I try to do a normal fetch with betterFetch , the library that power the better-auth, it not working the cookies are not getting propely , even when I use not brower fetch the cookie was not attached to the reqestion , the cookie was only attaching to the fetch call , when I use authClient, but I need the cookie to be attached for every request

<!-- gh-comment-id:2578356506 --> @Vijayabaskar56 commented on GitHub (Jan 8, 2025): ``` import Cookies from 'js-cookie'; export const client = hc<ApiRoutes>("http://localhost:3000/", { }); export const api = client.api; export async function test() { const res = await api.test.$get(); if (!res.ok) { throw new Error("server error"); } const data = await res.json(); return data; }; export async function testFetch() { const res = await betterFetch('http://localhost:3000/api/test'); console.log('cookie', getCookies({}).sessionData, Cookies.get()); if (!res.error) { throw new Error("server error"); } const data = await res.data; return data; } ``` Any help on my issue would be appreciated, I have cannot get the cookie with js-cookies, and I cannot set cokies to the hono rpc client, even when I try to do a normal fetch with betterFetch , the library that power the better-auth, it not working the cookies are not getting propely , even when I use not brower fetch the cookie was not attached to the reqestion , the cookie was only attaching to the fetch call , when I use authClient, but I need the cookie to be attached for every request
Author
Owner

@Vijayabaskar56 commented on GitHub (Jan 9, 2025):

hey , I figure that out , I forgot to include

  credentials: 'include'

in the header , that completly my mistake

here the solution , incase any-one is as dume as me,

export const client = hc<ApiRoutes>("http://localhost:3000/", {
 init: {
  credentials: 'include'
 }
});

I am close this issue , anyway thanks for the awasome library

<!-- gh-comment-id:2580508805 --> @Vijayabaskar56 commented on GitHub (Jan 9, 2025): hey , I figure that out , I forgot to include ``` credentials: 'include' ``` in the header , that completly my mistake here the solution , incase any-one is as dume as me, ``` export const client = hc<ApiRoutes>("http://localhost:3000/", { init: { credentials: 'include' } }); ``` I am close this issue , anyway thanks for the awasome library
Author
Owner

@nktnet1 commented on GitHub (Feb 18, 2025):

Hey @Vijayabaskar56,

Appreciate you posting the solution afterwards. I was stuck on a similar issue (React, Hono, tRPC) and got it working from the tip here.


At the time of writing, here's tRPC version 11 docs (source):

Send cookies cross-origin

If your API resides on a different origin than your front-end and you wish to send cookies to it, you will need to enable CORS on your server and send cookies with your requests by providing the option {credentials: "include"} to fetch.

The arguments provided to the fetch function used by tRPC can be modified as follow.

import { createTRPCClient, httpBatchLink } from '@trpc/client';
const client = createTRPCClient<AppRouter>({
  links: [
    httpBatchLink({
      url: 'YOUR_SERVER_URL',
      fetch(url, options) {
        return fetch(url, {
          ...options,
          credentials: 'include',
        });
      },
    }),
  ],
});

Note

You also need to enable CORS on your server by modifying your adapter, or the HTTP server which fronts your API. The best way to do this varies adapter-by-adapter and based on your hosting infrastructure, and individual adapters generally document this process where applicable.

<!-- gh-comment-id:2664423701 --> @nktnet1 commented on GitHub (Feb 18, 2025): Hey @Vijayabaskar56, Appreciate you posting the solution afterwards. I was stuck on a similar issue (React, Hono, tRPC) and got it working from the tip here. --- At the time of writing, here's tRPC **version 11** docs ([source](https://trpc.io/docs/client/cors)): > ## Send cookies cross-origin > > If your API resides on a different origin than your front-end and you wish to send cookies to it, you will need to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) on your server and send cookies with your requests by providing the option {credentials: "include"} to fetch. > > The arguments provided to the fetch function used by tRPC can be modified as follow. > ```ts > import { createTRPCClient, httpBatchLink } from '@trpc/client'; > const client = createTRPCClient<AppRouter>({ > links: [ > httpBatchLink({ > url: 'YOUR_SERVER_URL', > fetch(url, options) { > return fetch(url, { > ...options, > credentials: 'include', > }); > }, > }), > ], > }); > ``` > [!NOTE] > You also need to enable CORS on your server by modifying your adapter, or the HTTP server which fronts your API. The best way to do this varies adapter-by-adapter and based on your hosting infrastructure, and individual adapters generally document this process where applicable.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#8610