1

I am building a platform that offers different applications, the main platform is running on http://localhost and the applications will run each on a specific subdomain, at the moment I have an application running on http://sub.localhost.

I am using Nginx and Docker to host both the platform and the application, my goal would be to authenticate on http://localhost and use the session of the platform in the applications (subdomains), I have already taken a look at every single source/similar problem but could not find a solution, some of the sources I have read are the following:

At the moment this is my .env.local on the main platform:

NODE_ENV=development
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
GOOGLE_AUTH_URL=...
NEXTAUTH_URL=http://localhost/
NEXTAUTH_URL_INTERNAL=http://mygames:3000/
NEXTAUTH_SECRET=...
DATABASE_URL=...
NEXT_PUBLIC_API_KEY=...
NEXT_SECRET_API_KEY=...

The following is the .env.local of the application (subdomain):

NEXTAUTH_URL=http://sub.localhost/
NEXTAUTH_URL_INTERNAL=http://mygames:3000/
NEXTAUTH_SECRET=...
DATABASE_URL=...
NEXT_PUBLIC_API_KEY=...
NEXT_SECRET_API_KEY=...

The following is my [...nextauth].js for the main platform:

import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import prisma from '../../../lib/prisma';
import Stripe from 'stripe';

const getDomainWithoutSubdomain = url => {
  const urlParts = new URL(url).hostname.split('.');

  return urlParts
      .slice(0)
      .slice(-(urlParts.length === 4 ? 3 : 2))
      .join('.');
};

const hostName = getDomainWithoutSubdomain(process.env.NEXTAUTH_URL);

console.log("HOSTNAME", hostName);

const options = {
  secret: process.env.NEXTAUTH_SECRET,
  adapter: PrismaAdapter(prisma),
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
  pages: {
    signIn: '/signin'
  },
  callbacks: {
    async signIn({ user, account, profile, email, credentials }) {
      return true;
    },
    async redirect({ url, baseUrl }) {
      return baseUrl;
    },
    async session({ session, user, token }) {
      return { ...session, ...user };
    },
    async jwt({ token, user, account, profile, isNewUser }) {
      return token;
    }
  },
  cookies: {
    sessionToken: {
      name: process.env.NODE_ENV === 'production' ? `__Secure-next-auth.session-token` : 'next-auth.session-token',
      options: {
        httpOnly: true,
        sameSite: 'lax',
        path: '/',
        secure: process.env.NODE_ENV === 'production' ? true: false,
        domain: '.' + hostName
      }
    }
  }
}

export default (req, res) => NextAuth(req, res, options)

When I use getSession in the subdomain application I receive a null object, what can I do to solve this? Feel free to ask for anything for more details!

DRE
  • 263
  • 8
  • 35
  • Check out this example. https://github.com/vercel/examples/tree/main/solutions/subdomain-auth (Looks like you have already checked and created an issue in GitHub) – MC Naveen Sep 26 '22 at 13:08
  • @MCNaveen yes exactly, I have looked around that repository but it appears to be missing something because my code is exactly like that and does not work (also they do not show what they have done in the application that is running in the subdomain). – DRE Sep 26 '22 at 16:52
  • Did you find a solution? I am currently wanting to authenticate on example.com using next auth and share the same session across subdomains too. Little luck so far... If you made any progress please update the post :) Thanks – jacktim Feb 14 '23 at 09:02

1 Answers1

0

Spent ages looking for a solution...

Solution: https://github.com/nextauthjs/next-auth/discussions/4089#discussioncomment-2290660

TLDR; You cannot use localhost subdomains as intended. You must use example.com and app.example.com. To set these go to the hosts file in you system.

Follow the steps in the github post if needed

jacktim
  • 420
  • 4
  • 11