Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TanStack/Start useSession<>() does not persist on Safari, all auth examples are broken. #3492

Open
bhouston opened this issue Feb 20, 2025 · 1 comment

Comments

@bhouston
Copy link

bhouston commented Feb 20, 2025

Which project does this relate to?

Start

Describe the bug

This example, examples/react/start-basic-auth, only works in Firefox and Chrome. It does not work in Safari 18.3 on MacOS 15.3.1. I am using TanStack Start 1.107 (the latest) with TanStack Router 1.107 (the latest.)

The main issue is that login uses useSession<> from tanstack/start and it appears to not persist the cookie in Safari. I suspect there is slightly different cookie handling in Safari as compared to the other browsers.

Your Example Website or App

https://tanstack.com/start/latest/docs/framework/react/examples/start-basic-auth

Steps to Reproduce the Bug or Issue

Open up Safari on MacOS - I am using the latest release version for everything (no betas) - Safari 18.3 on MacOS 15.3.1.

If you haven't created a local account in the sqlite DB, Go to signup and create a new account.

Then go to login and try to log in. It will succeed in the login, but the top nav will continue to have "Login" listed, rather than your username/email with "Logout."

This is a sign that cookies are not persisting in Safari.

Expected behavior

Safari should work like Chrome and Firefox.

Screenshots or Videos

output.mp4

Platform

  • OS: MacOS 15.3.1
  • Browser: Safari 18.3

Additional context

No response

@bhouston
Copy link
Author

bhouston commented Feb 20, 2025

As an experiment, I tried my https://mycoder.ai on the problem with this prompt:

"This is a large monorepo with a lot of sub-packages. It is the monorepo for TanStack Router and TanStack Start. Within some package that is part of the TanStack Start product, there is a server side hook called useSession(). IT somehow creates cookies that are set on responses back to the client. The cookies persist when using Chrome and Firefox but they do not persist when using Safari, thus any code that uses useSession() does not actually work properly. Can you find the code for useSession() and then try to understand why the cookies it is trying to set are not persisting in Safari? . There is an example project here: examples/react/start-basic-auth that demonstrates the usage of useSession() and it is currently broken."

It's work: https://pastebin.com/FcGKdPbU

And it suggested this change to session.ts in the example:

export function useAppSession() {
  return useSession<SessionUser>({
    password: 'ChangeThisBeforeShippingToProdOrYouWillBeFired',

    // inserted by MyCoder.ai
    cookie: {
      // Set secure in production environments
      secure: process.env.NODE_ENV === 'production',
      // Use Lax for better compatibility while maintaining security
      sameSite: 'lax',
      // Prevent JavaScript access to the cookie
      httpOnly: true,
      // Set explicit expiration (30 days)
      maxAge: 30 * 24 * 60 * 60,
      // Ensure cookie is set for the root path
      path: '/'
    }
  })
}

This fixed the issue.

I think we may want to have better defaults that just work across browsers for the cookies that incorporates this change?

I have narrowed down that the key aspect of the change that fixed the issue was this line:

      // Set secure in production environments
      secure: process.env.NODE_ENV === 'production',

The docs say this: "Note be careful when setting 'secure' to true, as compliant clients will not send the cookie back to the server in the future if the browser does not have an HTTPS connection." This is the case in default vinxi dev mode.

I confirmed that somehow "secure" is being set to true and that is the problem. If I manually set it to false, it works in local dev, but if I set it to true, it fails.

The rest of the "fix" was extraneous.

The culprit is in H3 on this line: https://github.com/unjs/h3/blob/67e12ae157876c8e5cd8e686ccb6efb1e467861c/src/utils/session.ts#L37

Basically DEFAULT_COOKIE is used as defaults in updateSession: https://github.com/unjs/h3/blob/67e12ae157876c8e5cd8e686ccb6efb1e467861c/src/utils/session.ts#L153 and also in https://github.com/unjs/h3/blob/67e12ae157876c8e5cd8e686ccb6efb1e467861c/src/utils/session.ts#L217

So if you do not specify a value for "cookie.secure" it will end up as true and thus Safari development mode will fail to save cookies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant