DEV Community

Cover image for How to add next-auth to already implemented iron-session based authentication?
Mariusz
Mariusz

Posted on

How to add next-auth to already implemented iron-session based authentication?

Let's assume that our current solution uses iron-session JWT tokens like follows:

MyApp.getInitialProps = async function (appContext: AppContext) {
  const { req, res } = appContext.ctx;
  const DEFAULT_PROPS = {
    pageProps: {},
  };

  try {
    const session = await getIronSession(req!, res!, sessionOptions);
    if (session.user) {
      return {
        ...DEFAULT_PROPS,
        pageProps: {
          user: session.user,
        },
      };
    }

    return DEFAULT_PROPS;
  }
  catch {
    return DEFAULT_PROPS;
  }
}
Enter fullscreen mode Exit fullscreen mode

The main objective is to be backward compatible. We want to preserve current sessions and easily allow OAuth even for users didn't used any provider during registration.

Important part of following solutions:

  • expose Request / Response object to NextAuth
  • using decorator withIronSessionApiRoute we can decypher current JWT data or create the new token
  • we need to use the same JWT config object too (obviously) - sessionOptions

Final solution, [...nextauth].ts:

import { withIronSessionApiRoute } from "iron-session/next";
import { NextApiRequest, NextApiResponse } from "next";
import NextAuth, { AuthOptions } from "next-auth";

export default withIronSessionApiRoute((req: NextApiRequest, res: NextApiResponse) => {

  return NextAuth(req, res, {
    providers: [
      GoogleProvider({
        clientId: ENV_MAP.OAUTH_GOOGLE_CLIENT_ID,
        clientSecret: ENV_MAP.OAUTH_GOOGLE_SECRET,
      })
    ],
    ...
    callbacks: {
      async signIn({ account, profile }) {
        if (account?.provider === "google") {
          const user = await UserDAO.getByEmail(profile?.email || "");

          ...

          const userSerialized = serializeUser(user);
          req.session.user = userSerialized;
          req.session.save()
          return true;
        };

        return false;
      },

    }
  } as AuthOptions)}, sessionOptions);
Enter fullscreen mode Exit fullscreen mode

Top comments (0)