Search code examples
javascriptnext.jsnext-auth

NextAuth with Wild card / Custom Domains - Signin logic


I have a NextJS application. It's a multi-tenant SaaS application.

The app provides each customer with the option to use a subdomain on our site or to map their custom domain vis CNAME.

It allows our customers to allow their employees to login on their subdomain site or custom domain.

In the [...nextauth].js file, The following is the signIn callback, which is called after signin:

async signIn({ user, account, profile, email, credentials }) {
 return true
},

In this callback, I want to check which custom domain or subdomain the user is signing in from and then add some logic based on it. However, this callback doesn't have access to req headers. Then, how do I access the domain/hostname inside it? Depending on the domain, I want to allow/block signin or perform some other action.


Solution

  • It sounds like the following section in NextAuth documentation covers your use case:

    https://next-auth.js.org/configuration/initialization#advanced-initialization

    Any variable you create this way will be available in the NextAuth options as well, since they are in the same scope.

    import NextAuth from "next-auth"
    import { NextApiRequest, NextApiResponse } from "next"
    
    export default async function auth(req: NextApiRequest, res: NextApiResponse) {
      const { host } = req.headers; 
      // use the host value in NextAuth config below
    
      return await NextAuth(req, res, {
        // ...
      })
    }
    

    UPDATE:

    You can use the following pattern to access NextAuth config in API routes or getServerSideProps:

    import { IncomingMessage } from "http";
    import { NextApiRequest, NextApiResponse } from "next";
    import NextAuth, { NextAuthOptions } from "next-auth";
    
    export function authOptions(req: IncomingMessage): NextAuthOptions {
      const { host } = req.headers;
    
      return {
        // ...
      }
    };
    
    export default async function auth(req: NextApiRequest, res: NextApiResponse) {
        return await NextAuth(req, res, authOptions(req));
    }
    
    import { getServerSession } from "next-auth";
    import { NextApiRequest, NextApiResponse } from "next";
    import { authOptions } from "./auth/[...nextauth]";
    
    export default async function post(req: NextApiRequest, res: NextApiResponse) {
      const session = await getServerSession(req, res, authOptions(req));
      // ...
    }