[GH-ISSUE #2157] in production not getting session data after login #9072

Closed
opened 2026-04-13 04:22:15 -05:00 by GiteaMirror · 19 comments
Owner

Originally created by @SMD-1 on GitHub (Apr 6, 2025).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/2157

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Create an express project with postgresql and drizzle in Typescript
  2. Setup according to better-auth documentation https://www.better-auth.com/docs/installation
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "../db";
import { account, session, user, verification } from "../db/schema";

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
    schema: { user, account, session, verification },
  }),
  trustedOrigins: ["http://localhost:5173", "https://typiingspeed.netlify.app"],
  emailAndPassword: {
    enabled: true,
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    },
  },
});
  1. Create a UI using React+Vite+TS and setup auth-client according to documentation
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
  /** the base url of the server (optional if you're using the same domain) */
  baseURL: import.meta.env.VITE_API_BASE_URL,
});
  1. after login/signup fetch session using useSession()
  const { data: session, isPending, error, refetch } = authClient.useSession();
  1. Deployed Backend in cloud and frontend in Netlify

Current vs. Expected behavior

Current:

  • In production after logged in, cookies getting rejected to set getting this warning

Image

  • but in local everything is working as expeted and totally fine.
    Expected:
  • In production should fetch session after log in

What version of Better Auth are you using?

1.2.4

Provide environment information

- Ubuntu 22

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

Client

Auth config (if applicable)

import { betterAuth } from "better-auth"
export const auth = betterAuth({
  emailAndPassword: {  
    enabled: true
  },
});

Additional context

Below is the submit function for login with email

const handleSubmit = async (e: React.FormEvent): Promise<void> => {
    e.preventDefault();
    const response = await authClient.signIn.email(
      {
        email: email,
        password: password,
      },
      {
        onRequest: () => {
          setLoading(true);
        },
        onSuccess: () => {
          setLoading(false);
          navigate("/");
        },
        onError: (ctx) => {
          setError(ctx.error.message);
          setLoading(false);
        },
      }
    );
  };
Originally created by @SMD-1 on GitHub (Apr 6, 2025). Original GitHub issue: https://github.com/better-auth/better-auth/issues/2157 ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce 1. Create an express project with postgresql and drizzle in Typescript 2. Setup according to better-auth documentation https://www.better-auth.com/docs/installation ```js import { betterAuth } from "better-auth"; import { drizzleAdapter } from "better-auth/adapters/drizzle"; import { db } from "../db"; import { account, session, user, verification } from "../db/schema"; export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", schema: { user, account, session, verification }, }), trustedOrigins: ["http://localhost:5173", "https://typiingspeed.netlify.app"], emailAndPassword: { enabled: true, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }, }, }); ``` 3. Create a UI using React+Vite+TS and setup auth-client according to documentation ```js import { createAuthClient } from "better-auth/react"; export const authClient = createAuthClient({ /** the base url of the server (optional if you're using the same domain) */ baseURL: import.meta.env.VITE_API_BASE_URL, }); ``` 4. after login/signup fetch session using useSession() ```ts const { data: session, isPending, error, refetch } = authClient.useSession(); ``` 5. Deployed Backend in cloud and frontend in Netlify ### Current vs. Expected behavior Current: - In production after logged in, cookies getting rejected to set getting this warning ![Image](https://github.com/user-attachments/assets/a913a5ba-a7e5-4a7b-884c-8bddc40d744a) - but in local everything is working as expeted and totally fine. Expected: - In production should fetch session after log in ### What version of Better Auth are you using? 1.2.4 ### Provide environment information ```bash - Ubuntu 22 ``` ### Which area(s) are affected? (Select all that apply) Client ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" export const auth = betterAuth({ emailAndPassword: { enabled: true }, }); ``` ### Additional context Below is the submit function for login with email ```jsx const handleSubmit = async (e: React.FormEvent): Promise<void> => { e.preventDefault(); const response = await authClient.signIn.email( { email: email, password: password, }, { onRequest: () => { setLoading(true); }, onSuccess: () => { setLoading(false); navigate("/"); }, onError: (ctx) => { setError(ctx.error.message); setLoading(false); }, } ); }; ```
GiteaMirror added the locked label 2026-04-13 04:22:15 -05:00
Author
Owner

@Kinfe123 commented on GitHub (Apr 7, 2025):

can you please update your client auth config like this -

import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
  /** the base url of the server (optional if you're using the same domain) */
  baseURL: import.meta.env.VITE_API_BASE_URL,
 fetchOptions: {
    credentials: "include",
  }
});
<!-- gh-comment-id:2782111258 --> @Kinfe123 commented on GitHub (Apr 7, 2025): can you please update your client auth config like this - ```ts import { createAuthClient } from "better-auth/react"; export const authClient = createAuthClient({ /** the base url of the server (optional if you're using the same domain) */ baseURL: import.meta.env.VITE_API_BASE_URL, fetchOptions: { credentials: "include", } }); ```
Author
Owner

@SMD-1 commented on GitHub (Apr 7, 2025):

@Kinfe123, I have tried this but didn't work.
actually cookies are not getting set after login/signup.

<!-- gh-comment-id:2782202751 --> @SMD-1 commented on GitHub (Apr 7, 2025): @Kinfe123, I have tried this but didn't work. actually cookies are not getting set after login/signup.
Author
Owner

@Kinfe123 commented on GitHub (Apr 7, 2025):

oh i see since it is not on same domain, can you add flags like below on your auth config of your backend

advanced: {
    cookie: {
      sameSite: 'none',
      secure: true,
      domain: process.env.COOKIE_DOMAIN || undefined,
      path: '/',
    }
  },

the cookie domain is actually your backend domain

<!-- gh-comment-id:2782236716 --> @Kinfe123 commented on GitHub (Apr 7, 2025): oh i see since it is not on same domain, can you add flags like below on your auth config of your backend ```ts advanced: { cookie: { sameSite: 'none', secure: true, domain: process.env.COOKIE_DOMAIN || undefined, path: '/', } }, ``` the cookie domain is actually your backend domain
Author
Owner

@SMD-1 commented on GitHub (Apr 7, 2025):

Tried this also but not working 🥺, getting same error

Image

<!-- gh-comment-id:2782676027 --> @SMD-1 commented on GitHub (Apr 7, 2025): Tried this also but not working 🥺, getting same error ![Image](https://github.com/user-attachments/assets/1c0fceac-ad5e-482e-9834-2a068912cfb0)
Author
Owner

@Kinfe123 commented on GitHub (Apr 7, 2025):

Can you send your backend auth config

<!-- gh-comment-id:2782685957 --> @Kinfe123 commented on GitHub (Apr 7, 2025): Can you send your backend auth config
Author
Owner

@SMD-1 commented on GitHub (Apr 7, 2025):

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "pg",
    schema: { user, account, session, verification },
  }),
  trustedOrigins: ["http://localhost:5173", "https://typiingspeed.netlify.app"],
  advanced: {
    crossSubDomainCookies: {
      enabled: true,
      domain: process.env.COOKIE_DOMAIN || undefined, // Domain with a leading period
    },
    defaultCookieAttributes: {
      secure: true,
      // httpOnly: true,
      sameSite: "none", // Allows CORS-based cookie sharing across subdomains
      // partitioned: true, // New browser standards will mandate this for foreign cookies
    },
  },
  emailAndPassword: {
    enabled: true,
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    },
  },
});

@Kinfe123, here is my repo link for ref: https://github.com/SMD-1/typing-speed-api

<!-- gh-comment-id:2782716208 --> @SMD-1 commented on GitHub (Apr 7, 2025): ```js export const auth = betterAuth({ database: drizzleAdapter(db, { provider: "pg", schema: { user, account, session, verification }, }), trustedOrigins: ["http://localhost:5173", "https://typiingspeed.netlify.app"], advanced: { crossSubDomainCookies: { enabled: true, domain: process.env.COOKIE_DOMAIN || undefined, // Domain with a leading period }, defaultCookieAttributes: { secure: true, // httpOnly: true, sameSite: "none", // Allows CORS-based cookie sharing across subdomains // partitioned: true, // New browser standards will mandate this for foreign cookies }, }, emailAndPassword: { enabled: true, }, socialProviders: { google: { clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }, }, }); ``` @Kinfe123, here is my repo link for ref: https://github.com/SMD-1/typing-speed-api
Author
Owner

@brunocalou commented on GitHub (Apr 7, 2025):

I have the same issue.

It's possible to reproduce it locally by setting the useSecureCookies setting to true

<!-- gh-comment-id:2783335575 --> @brunocalou commented on GitHub (Apr 7, 2025): I have the same issue. It's possible to reproduce it locally by setting the `useSecureCookies` setting to `true`
Author
Owner

@Kinfe123 commented on GitHub (Apr 8, 2025):

oh

export const auth = betterAuth({
database: drizzleAdapter(db, {
provider: "pg",
schema: { user, account, session, verification },
}),
trustedOrigins: ["http://localhost:5173", "https://typiingspeed.netlify.app"],
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: process.env.COOKIE_DOMAIN || undefined, // Domain with a leading period
},
defaultCookieAttributes: {
secure: true,
// httpOnly: true,
sameSite: "none", // Allows CORS-based cookie sharing across subdomains
// partitioned: true, // New browser standards will mandate this for foreign cookies
},
},
emailAndPassword: {
enabled: true,
},
socialProviders: {
google: {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
});
@Kinfe123, here is my repo link for ref: https://github.com/SMD-1/typing-speed-api

oh if that is the case so use should set useSecureCookies: process.env.NODE_ENV === "production" which will be true if we are on prod

<!-- gh-comment-id:2787031913 --> @Kinfe123 commented on GitHub (Apr 8, 2025): oh > export const auth = betterAuth({ > database: drizzleAdapter(db, { > provider: "pg", > schema: { user, account, session, verification }, > }), > trustedOrigins: ["http://localhost:5173", "https://typiingspeed.netlify.app"], > advanced: { > crossSubDomainCookies: { > enabled: true, > domain: process.env.COOKIE_DOMAIN || undefined, // Domain with a leading period > }, > defaultCookieAttributes: { > secure: true, > // httpOnly: true, > sameSite: "none", // Allows CORS-based cookie sharing across subdomains > // partitioned: true, // New browser standards will mandate this for foreign cookies > }, > }, > emailAndPassword: { > enabled: true, > }, > socialProviders: { > google: { > clientId: process.env.GOOGLE_CLIENT_ID as string, > clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, > }, > }, > }); > [@Kinfe123](https://github.com/Kinfe123), here is my repo link for ref: https://github.com/SMD-1/typing-speed-api oh if that is the case so use should set `useSecureCookies: process.env.NODE_ENV === "production"` which will be true if we are on prod
Author
Owner

@brunocalou commented on GitHub (Apr 9, 2025):

But setting it to true doesn't work in prod, it just replicates the issue on local environment

<!-- gh-comment-id:2787985761 --> @brunocalou commented on GitHub (Apr 9, 2025): But setting it to true doesn't work in prod, it just replicates the issue on local environment
Author
Owner

@brunocalou commented on GitHub (Apr 9, 2025):

Oh, I got it to work now.

You can set the useSecureCookies on local env to process.env.NODE_ENV === "production". Also, the credentials: "include" should be present when calling the endpoint on the front-end.

The real problem is that there was a cookie already set on client. The sign in function was creating one more cookie, but I think the old one was being used instead. I've erased both and now it's working properly, I can login and logout multiple times

Image
<!-- gh-comment-id:2788045622 --> @brunocalou commented on GitHub (Apr 9, 2025): Oh, I got it to work now. You can set the `useSecureCookies` on local env to `process.env.NODE_ENV === "production"`. Also, the `credentials: "include"` should be present when calling the endpoint on the front-end. The real problem is that there was a cookie already set on client. The sign in function was creating one more cookie, but I think the old one was being used instead. I've erased both and now it's working properly, I can login and logout multiple times <img width="520" alt="Image" src="https://github.com/user-attachments/assets/85715d8f-81cc-4b43-91e4-ceebeb08493a" />
Author
Owner

@Kinfe123 commented on GitHub (Apr 9, 2025):

Glad it works.

<!-- gh-comment-id:2788189645 --> @Kinfe123 commented on GitHub (Apr 9, 2025): Glad it works.
Author
Owner

@SMD-1 commented on GitHub (Apr 9, 2025):

Oh, I got it to work now.

You can set the useSecureCookies on local env to process.env.NODE_ENV === "production". Also, the credentials: "include" should be present when calling the endpoint on the front-end.

The real problem is that there was a cookie already set on client. The sign in function was creating one more cookie, but I think the old one was being used instead. I've erased both and now it's working properly, I can login and logout multiple times

Image

@brunocalou is it working in production for you?

<!-- gh-comment-id:2788607436 --> @SMD-1 commented on GitHub (Apr 9, 2025): > Oh, I got it to work now. > > You can set the `useSecureCookies` on local env to `process.env.NODE_ENV === "production"`. Also, the `credentials: "include"` should be present when calling the endpoint on the front-end. > > The real problem is that there was a cookie already set on client. The sign in function was creating one more cookie, but I think the old one was being used instead. I've erased both and now it's working properly, I can login and logout multiple times > > <img alt="Image" width="520" src="https://private-user-images.githubusercontent.com/5948318/431624694-85715d8f-81cc-4b43-91e4-ceebeb08493a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDQxODMxNDcsIm5iZiI6MTc0NDE4Mjg0NywicGF0aCI6Ii81OTQ4MzE4LzQzMTYyNDY5NC04NTcxNWQ4Zi04MWNjLTRiNDMtOTFlNC1jZWViZWIwODQ5M2EucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDQwOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA0MDlUMDcxNDA3WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MzAxYmNmMGM1ZjM0YzUwMzY1NzhmNDU0OTQyZDQ0N2EyYTZmNTg3MmVmMmFmZDM4M2U0YzdhN2ZjODIyYzc4ZiZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.dvHxY3vQk1mO_0HBUXw81nWUzVf2zlRYQtjt7f4fvn8"> @brunocalou is it working in production for you?
Author
Owner

@Kinfe123 commented on GitHub (Apr 9, 2025):

is there any prob you are facing ?

<!-- gh-comment-id:2788624029 --> @Kinfe123 commented on GitHub (Apr 9, 2025): is there any prob you are facing ?
Author
Owner

@brunocalou commented on GitHub (Apr 9, 2025):

@SMD-1 yeah, I can login and logout multiple times and it always works as expected

<!-- gh-comment-id:2789933614 --> @brunocalou commented on GitHub (Apr 9, 2025): @SMD-1 yeah, I can login and logout multiple times and it always works as expected
Author
Owner

@tigawanna commented on GitHub (Apr 13, 2025):

this worked for me but is kinda unreliable with oauth


  advanced: {
    crossSubDomainCookies: {
      enabled: true,
      // domain: process.env.COOKIE_DOMAIN || undefined,
    },
    cookie: {
      sameSite: "none",
      secure: true,
      // domain: process.env.COOKIE_DOMAIN || undefined,
      path: "/",
    },
    defaultCookieAttributes: {
      secure: true,
      // httpOnly: true,
      sameSite: "none", // Allows CORS-based cookie sharing across subdomains
      // partitioned: true, // New browser standards will mandate this for foreign cookies
    },
  },

<!-- gh-comment-id:2800063002 --> @tigawanna commented on GitHub (Apr 13, 2025): this worked for me but is kinda unreliable with oauth ```ts advanced: { crossSubDomainCookies: { enabled: true, // domain: process.env.COOKIE_DOMAIN || undefined, }, cookie: { sameSite: "none", secure: true, // domain: process.env.COOKIE_DOMAIN || undefined, path: "/", }, defaultCookieAttributes: { secure: true, // httpOnly: true, sameSite: "none", // Allows CORS-based cookie sharing across subdomains // partitioned: true, // New browser standards will mandate this for foreign cookies }, }, ```
Author
Owner

@taxhubng commented on GitHub (Apr 26, 2025):

this worked for me

<!-- gh-comment-id:2832695767 --> @taxhubng commented on GitHub (Apr 26, 2025): this worked for me
Author
Owner

@HenriqueBragaMoreira commented on GitHub (Sep 1, 2025):

this worked for me but is kinda unreliable with oauth

advanced: {
crossSubDomainCookies: {
enabled: true,
// domain: process.env.COOKIE_DOMAIN || undefined,
},
cookie: {
sameSite: "none",
secure: true,
// domain: process.env.COOKIE_DOMAIN || undefined,
path: "/",
},
defaultCookieAttributes: {
secure: true,
// httpOnly: true,
sameSite: "none", // Allows CORS-based cookie sharing across subdomains
// partitioned: true, // New browser standards will mandate this for foreign cookies
},
},

I tried this solution, but it still returns a 307 status code (infinite redirect) to the login page. After that, it responds with 200 and sets cookies, but nothing seems to catch the cookies in production (I'm using cross-origin domains).

<!-- gh-comment-id:3243041362 --> @HenriqueBragaMoreira commented on GitHub (Sep 1, 2025): > this worked for me but is kinda unreliable with oauth > > advanced: { > crossSubDomainCookies: { > enabled: true, > // domain: process.env.COOKIE_DOMAIN || undefined, > }, > cookie: { > sameSite: "none", > secure: true, > // domain: process.env.COOKIE_DOMAIN || undefined, > path: "/", > }, > defaultCookieAttributes: { > secure: true, > // httpOnly: true, > sameSite: "none", // Allows CORS-based cookie sharing across subdomains > // partitioned: true, // New browser standards will mandate this for foreign cookies > }, > }, I tried this solution, but it still returns a 307 status code (infinite redirect) to the login page. After that, it responds with 200 and sets cookies, but nothing seems to catch the cookies in production (I'm using cross-origin domains).
Author
Owner

@atjain02 commented on GitHub (Dec 5, 2025):

I was running into the same issue and adding @tigawanna's solution actually made it stop working locally as well. Any luck?

<!-- gh-comment-id:3615253639 --> @atjain02 commented on GitHub (Dec 5, 2025): I was running into the same issue and adding @tigawanna's solution actually made it stop working locally as well. Any luck?
Author
Owner

@HenriqueBragaMoreira commented on GitHub (Dec 5, 2025):

I was running into the same issue and adding @tigawanna's solution actually made it stop working locally as well. Any luck?

I managed to solve this issue in production. Since I'm using Next.js, I configured a rewrite rule so that any request to my backend appears to come from the same frontend URL on Vercel, while actually being routed to my backend hosted on another domain (Render):

rewrites: async () => {
return {
beforeFiles: [
{
source: "/api/:path*",
destination: new URL(
"/api/:path*",
process.env.NEXT_PUBLIC_API_URL
).toString(),
},
],
afterFiles: [],
fallback: [],
};
}

In this case, I added the /api prefix to all my backend routes so I could properly track and rewrite them and it worked well.

<!-- gh-comment-id:3615340930 --> @HenriqueBragaMoreira commented on GitHub (Dec 5, 2025): > I was running into the same issue and adding [@tigawanna](https://github.com/tigawanna)'s solution actually made it stop working locally as well. Any luck? I managed to solve this issue in production. Since I'm using Next.js, I configured a rewrite rule so that any request to my backend appears to come from the same frontend URL on Vercel, while actually being routed to my backend hosted on another domain (Render): rewrites: async () => { return { beforeFiles: [ { source: "/api/:path*", destination: new URL( "/api/:path*", process.env.NEXT_PUBLIC_API_URL ).toString(), }, ], afterFiles: [], fallback: [], }; } In this case, I added the /api prefix to all my backend routes so I could properly track and rewrite them and it worked well.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#9072