I would like to use google authentication using subdomains, but my subdomains are dynamic. #595

Closed
opened 2026-03-13 07:55:48 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @Iagopersantos on GitHub (Jan 27, 2025).

Is this suited for github?

  • Yes, this is suited for github

I would like to use google authentication using subdomains, but my subdomains are dynamic.

Normally in the google api, I need to be specific when naming my subdomain, and it is impossible to pass “*” for dynamic cases, and I would like to use better auth to redirect to a domain that is specified in the google api, and return to the domain with the subdomain, for example:

The user will be at: https://subomain.domain.com/
When they log in with google, they go to the authentication domain: https://auth.domain.com/
After authentication, I want the user to be redirected to the domain: https://subomain.domain.com/

Being validated and authenticated, taking with them the browser cookies to validate the authentication.

Would it be possible to do this with better-auth?

Describe the solution you'd like

Possibility of logging in with dynamic subdomains, redirecting to a domain defined as auth and returning to the subdomain.

Describe alternatives you've considered

Use the proxy model that oauth already uses to redirect and authenticate the user.

Additional context

No response

Originally created by @Iagopersantos on GitHub (Jan 27, 2025). ### Is this suited for github? - [x] Yes, this is suited for github ### Is your feature request related to a problem? Please describe. I would like to use google authentication using subdomains, but my subdomains are dynamic. Normally in the google api, I need to be specific when naming my subdomain, and it is impossible to pass “*” for dynamic cases, and I would like to use better auth to redirect to a domain that is specified in the google api, and return to the domain with the subdomain, for example: The user will be at: https://subomain.domain.com/ When they log in with google, they go to the authentication domain: https://auth.domain.com/ After authentication, I want the user to be redirected to the domain: https://subomain.domain.com/ Being validated and authenticated, taking with them the browser cookies to validate the authentication. Would it be possible to do this with better-auth? ### Describe the solution you'd like Possibility of logging in with dynamic subdomains, redirecting to a domain defined as auth and returning to the subdomain. ### Describe alternatives you've considered Use the proxy model that oauth already uses to redirect and authenticate the user. ### Additional context _No response_
Author
Owner

@Alfredao commented on GitHub (May 16, 2025):

I have the exact same use case and would love some guidance

I want users to initiate login from https://subdomain.domain.com, redirect to https://auth.domain.com (where Better Auth is hosted), and then return to the original subdomain after Google login is successful, while keeping session cookies working.

I’m migrating from next-auth, where this is already supported. Their signIn function allows passing a redirectTo parameter like this:

signIn('google', { redirectTo :  'https://subdomain.domain.com'})

This enables us to initiate login from a subdomain and return the user there after authentication.

Is there an equivalent way to achieve this with Better Auth?

Thanks in advance 🙏

@Alfredao commented on GitHub (May 16, 2025): I have the exact same use case and would love some guidance I want users to initiate login from https://subdomain.domain.com, redirect to https://auth.domain.com (where Better Auth is hosted), and then return to the original subdomain after Google login is successful, while keeping session cookies working. I’m migrating from next-auth, where this is already supported. Their signIn function allows passing a redirectTo parameter like this: ```js signIn('google', { redirectTo : 'https://subdomain.domain.com'}) ``` This enables us to initiate login from a subdomain and return the user there after authentication. Is there an equivalent way to achieve this with Better Auth? Thanks in advance 🙏
Author
Owner

@DaxSoft commented on GitHub (May 27, 2025):

I'm doing this. While I'm yet to develop the solution for the cors, at least the redirect is working. If you want to try and check it. https://fear.travelerspentales.com/

It's basically some tricks with nextjs middleware and cookies (and callbackUrl).
I'll drop the answer if I create it.

@DaxSoft commented on GitHub (May 27, 2025): I'm doing this. While I'm yet to develop the solution for the cors, at least the redirect is working. If you want to try and check it. https://fear.travelerspentales.com/ It's basically some tricks with nextjs middleware and cookies (and callbackUrl). I'll drop the answer if I create it.
Author
Owner

@DaxSoft commented on GitHub (May 31, 2025):

Ok, to do it, pretty simple.

You can check a live example here: https://fear.travelerspentales.com/

To do it:

  • First you setup this setting on better-auth server side.

const isProduction = NEXT_PUBLIC_BASE_URL?.includes('travelerspentales.com');

    crossSubDomainCookies: isProduction
      ? {
          enabled: true,
          domain: NEXT_PUBLIC_SUBDOMAIN_URL, // NEXT_PUBLIC_SUBDOMAIN_URL=.travelerspentales.com
        }
      : undefined,
    defaultCookieAttributes: isProduction
      ? {
          secure: true,
          httpOnly: true,
          sameSite: 'none', // Allows CORS-based cookie sharing across subdomains
          partitioned: true, // New browser standards will mandate this for foreign cookies
        }
      : undefined,
  },```

Then, on nextjs middleware you do:

```const origin = req.headers.get('origin') ?? '';
    if (origin.endsWith('.travelerspentales.com')) {
      response.headers.set('Access-Control-Allow-Origin', origin);
      // if you ever need preflight, you can also add:
      // res.headers.set('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
      // res.headers.set('Access-Control-Allow-Headers', 'Authorization,Content-Type');
    }```


Also, you do on middleware

private hostHasSubdomain(): boolean {
const h = this.host;
if (h === BASE_DOMAIN || h === WWW_BASE_DOMAIN) return false;
return h.endsWith(.${BASE_DOMAIN});
}

/**

  • Handles only the /api/auth/* routes:
  • – if no subdomain → let it through
  • – if subdomain → rewrite to same path on that subdomain
    /
    private _handleAuthApi(): NextResponse {
    if (!this.hostHasSubdomain()) {
    // no tenant: fall back to default /api/auth/

    return NextResponse.next();
    }
// tenant subdomain: force the auth call back onto that subdomain
const url = this.req.nextUrl.clone();
url.hostname = this.host;
return NextResponse.rewrite(url, { request: { headers: this.rewriteHeaders } });

}



Then, on the subdomain folder of your nextjs project, you do:

```'use client';

import { fetcher } from '@/config/swr';
import { Session } from '@/types/auth';
import React, { useState } from 'react';
import useSWR from 'swr';

export type AuthContextProps = {
  data: Session | undefined;
  isLoading: boolean;
  refetch: () => void;
  signOut: (callback: () => void) => Promise<void>;
  isExiting: boolean;
};

type AuthContextProviderProps = {
  children: React.ReactNode;
};

export const AuthContext = React.createContext<AuthContextProps>({} as AuthContextProps);

export function AuthProvider({ children }: AuthContextProviderProps) {
  const [isExiting, setIsExiting] = useState(false);
  const { isLoading, data, mutate } = useSWR<Session>('/api/auth/get-session', fetcher);

  const refetch = () => {
    mutate();
  };

  const signOut = async (callback: () => void) => {
    setIsExiting(true);

    try {
      const response = await fetch('/api/auth/sign-out', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        throw new Error(`Sign out failed: ${response.statusText}`);
      }
    } catch (error) {
      console.error('Error during sign out:', error);
    } finally {
      setIsExiting(false);
    }
  };

  return (
    <AuthContext.Provider value={{ data, isLoading, refetch, signOut, isExiting }}>{children}</AuthContext.Provider>
  );
}

Hope it helps you. For better-auth, it would be nice to have the option to fetch using endpoint, and the host be automatically set as the origin host

@DaxSoft commented on GitHub (May 31, 2025): Ok, to do it, pretty simple. You can check a live example here: https://fear.travelerspentales.com/ To do it: - First you setup this setting on better-auth server side. ```const isProduction = NEXT_PUBLIC_BASE_URL?.includes('travelerspentales.com');``` ```advanced: { crossSubDomainCookies: isProduction ? { enabled: true, domain: NEXT_PUBLIC_SUBDOMAIN_URL, // NEXT_PUBLIC_SUBDOMAIN_URL=.travelerspentales.com } : undefined, defaultCookieAttributes: isProduction ? { secure: true, httpOnly: true, sameSite: 'none', // Allows CORS-based cookie sharing across subdomains partitioned: true, // New browser standards will mandate this for foreign cookies } : undefined, },``` Then, on nextjs middleware you do: ```const origin = req.headers.get('origin') ?? ''; if (origin.endsWith('.travelerspentales.com')) { response.headers.set('Access-Control-Allow-Origin', origin); // if you ever need preflight, you can also add: // res.headers.set('Access-Control-Allow-Methods', 'GET,POST,OPTIONS'); // res.headers.set('Access-Control-Allow-Headers', 'Authorization,Content-Type'); }``` Also, you do on middleware ``` private hostHasSubdomain(): boolean { const h = this.host; if (h === BASE_DOMAIN || h === WWW_BASE_DOMAIN) return false; return h.endsWith(`.${BASE_DOMAIN}`); } /** * Handles only the /api/auth/* routes: * – if no subdomain → let it through * – if subdomain → rewrite to same path on that subdomain */ private _handleAuthApi(): NextResponse { if (!this.hostHasSubdomain()) { // no tenant: fall back to default /api/auth/* return NextResponse.next(); } // tenant subdomain: force the auth call back onto that subdomain const url = this.req.nextUrl.clone(); url.hostname = this.host; return NextResponse.rewrite(url, { request: { headers: this.rewriteHeaders } }); } ``` Then, on the subdomain folder of your nextjs project, you do: ```'use client'; import { fetcher } from '@/config/swr'; import { Session } from '@/types/auth'; import React, { useState } from 'react'; import useSWR from 'swr'; export type AuthContextProps = { data: Session | undefined; isLoading: boolean; refetch: () => void; signOut: (callback: () => void) => Promise<void>; isExiting: boolean; }; type AuthContextProviderProps = { children: React.ReactNode; }; export const AuthContext = React.createContext<AuthContextProps>({} as AuthContextProps); export function AuthProvider({ children }: AuthContextProviderProps) { const [isExiting, setIsExiting] = useState(false); const { isLoading, data, mutate } = useSWR<Session>('/api/auth/get-session', fetcher); const refetch = () => { mutate(); }; const signOut = async (callback: () => void) => { setIsExiting(true); try { const response = await fetch('/api/auth/sign-out', { method: 'POST', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { throw new Error(`Sign out failed: ${response.statusText}`); } } catch (error) { console.error('Error during sign out:', error); } finally { setIsExiting(false); } }; return ( <AuthContext.Provider value={{ data, isLoading, refetch, signOut, isExiting }}>{children}</AuthContext.Provider> ); } ``` Hope it helps you. For better-auth, it would be nice to have the option to fetch using endpoint, and the host be automatically set as the origin host
Author
Owner

@dosubot[bot] commented on GitHub (Aug 30, 2025):

Hi, @Iagopersantos. I'm Dosu, and I'm helping the better-auth team manage their backlog and am marking this issue as stale.

Issue Summary:

  • You requested support for Google authentication on dynamic subdomains using a fixed auth domain with redirects, due to Google API restrictions on wildcard redirect URIs.
  • Another user, Alfredao, expressed a similar need for functionality like next-auth's redirectTo in better-auth.
  • DaxSoft contributed a working solution involving Next.js middleware, cross-subdomain cookies, and CORS headers, including detailed code and a live demo.
  • The solution effectively enables seamless login flows across dynamic subdomains with better-auth.
  • A suggestion was made for better-auth to improve by auto-setting the host based on the request origin.

Next Steps:

  • Please let me know if this issue is still relevant to the latest version of better-auth by commenting here.
  • If I don’t hear back within 7 days, I will automatically close this issue.

Thanks for your understanding and contribution!

@dosubot[bot] commented on GitHub (Aug 30, 2025): Hi, @Iagopersantos. I'm [Dosu](https://dosu.dev), and I'm helping the better-auth team manage their backlog and am marking this issue as stale. **Issue Summary:** - You requested support for Google authentication on dynamic subdomains using a fixed auth domain with redirects, due to Google API restrictions on wildcard redirect URIs. - Another user, Alfredao, expressed a similar need for functionality like next-auth's redirectTo in better-auth. - DaxSoft contributed a working solution involving Next.js middleware, cross-subdomain cookies, and CORS headers, including detailed code and a live demo. - The solution effectively enables seamless login flows across dynamic subdomains with better-auth. - A suggestion was made for better-auth to improve by auto-setting the host based on the request origin. **Next Steps:** - Please let me know if this issue is still relevant to the latest version of better-auth by commenting here. - If I don’t hear back within 7 days, I will automatically close this issue. Thanks for your understanding and contribution!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#595