jherr / next-auth-v5

Code for a video on Next-Auth v5 beta.
32 stars 14 forks source link

next-auth-v5 when deployed in Vercel, problems with req.auth #1

Closed rodrigc closed 1 month ago

rodrigc commented 1 month ago

Thanks for your video Next-Auth v5 is Almost Here! Learn it Fast on the NextJS App Router TODAY! and your code example.

It helped me a lot!

I am testing it out now, and I am having a problem when trying to run in Vercel.

  1. I forked your repository, and added more debugging in the middleware: https://github.com/rodrigc/next-auth-v5/blob/main/src/middleware.ts#L9
  2. Everything works fine when testing locally on my laptop.
  3. When I deploy to Vercel, I see in my debugging that console.log(req.auth); shows:
Session: undefined
Auth object: {
  message: 'There was a problem with the server configuration. Check the server logs for more information.'
}

Any ideas what the problem might be? Is this a bug in authjs.dev or Vercel?

Thanks for your help.

jherr commented 1 month ago

You're going to have to add a lot more specificity to this bug. Are the environment variables set properly on Vercel? Honestly, this probably isn't a bug in any of it. It's just not configured properly, as it says.

rodrigc commented 1 month ago

I kept this repro case minimal, by just taking your repository. In https://github.com/rodrigc/next-auth-v5/blob/main/.env , where the only env variable I set was AUTH_SECRET, as mentioned here: https://authjs.dev/reference/nextjs#environment-variable-inference

jherr commented 1 month ago

Are you sure that AUTH_SECRET is set in the Vercel environment? Not just in the .env file. But in the Vercel deployment environment?

rodrigc commented 1 month ago

You are correct. After adding more debugging to src/middleware.ts to console.log(process.env.AUTH_SECRET); I saw that AUTH_SECRET was not being set. Looks like deploying with Vercel does not automatically pick up environment variables from .env. Environment variables either need to be set via the vercel CLI or in the vercel console.

rodrigc commented 1 month ago

For this line: https://github.com/jherr/next-auth-v5/blob/main/src/middleware.ts#L10

  if (!req.auth && reqUrl?.pathname !== "/") {

it looks like req.auth can be non-null, but it will be populated with req.auth.message which is a string error message.

Do you think that it would be correct to change this check to something like:

  if (!req.auth?.user && reqUrl?.pathname !== "/") {

The NextAuthRequest interface mentions that auth can be a Session or null, and does not indicate that req.auth can by in an error state where req.auth.message is populated. Do you think that is a bug on nextauth's part?

jherr commented 1 month ago

Unless the type definitions are wrong then it's not an issue with nextauth. If req.auth.user without the ! is invalid then it's not an issue with nextauth. I would go with what works. If req.auth?.user works, then do that.

rodrigc commented 1 month ago

What do you think of this function (which I get with the help of Claude.ai)?


import { NextResponse } from "next/server";
import { auth, BASE_PATH } from "@/auth";
import type { Session } from "next-auth";

function isValidSession(auth: Session | null): auth is Session {
  if (!auth) return false;

  if (typeof auth !== 'object') return false;

  if (!('expires' in auth) || typeof auth.expires !== 'string') return false;

  // Check if expires is a valid ISO date string
  if (isNaN(Date.parse(auth.expires))) return false;

  // Check if the session has not expired
  if (new Date(auth.expires) < new Date()) return false;

  // Optionally, check for user object if your sessions always include it
  if ('user' in auth) {
    if (typeof auth.user !== 'object' || auth.user === null) return false;
    // Add more specific user checks if needed
  }

  return true;
}

export default auth((req) => {
  const reqUrl = new URL(req.url);
  if (!isValidSession(req.auth) && reqUrl?.pathname !== "/") {
    return NextResponse.redirect(
      new URL(
        `${BASE_PATH}/signin?callbackUrl=${encodeURIComponent(
          reqUrl?.pathname
        )}`,
        req.url
      )
    );
  }
});

I looked around the source code of next-auth and did not see a function similar to isValidSession()

jherr commented 1 month ago

Seems a bit excessive to me. But a better place for this conversation would be on the nextauth github repo.

rodrigc commented 1 month ago

OK. I created https://github.com/nextauthjs/next-auth/issues/11780 and will add details there.