psudo
psudo

Reputation: 1568

Logout on token expire next js next auth v4

I have the following code in authOptions.ts in next js 14 with next auth v4. I'm using external jwt for backend.

import NextAuth, { NextAuthOptions } from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import { JWT } from "next-auth/jwt"

const API_ENDPOINT =
  process.env.NEXT_PUBLIC_API_URL || "http://myapp.test/api"


class CustomError extends Error {
  status: number;

  constructor(message: string, status: number) {
    super(message);
    this.name = this.constructor.name;
    this.status = status;
    Error.captureStackTrace(this, this.constructor);
  }
}

const authOptions: NextAuthOptions = {
  providers: [
    CredentialsProvider({
      type: "credentials",
      name: "Email and Password",
      credentials: {
        email: { label: "Email", type: "email", placeholder: "Your Email" },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        console.log(credentials)
        if (!credentials?.email || !credentials?.password) return null

        const { email, password } = credentials

        const res = await fetch(`${API_ENDPOINT}/auth/login`, {
          method: "POST",
          body: JSON.stringify({
            email,
            password,
          }),
          headers: {
            "Content-Type": "application/json",
            Accept: "application/json",
          },
        })

        const response = await res.json()
        if (res.ok) {
          return response.data
        } else {
          throw new CustomError(response.message, response.status);
        }
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user }) {

      if (user) {
        return { ...token, ...user }
      }

      return token
    },
    async session({ token, session }) {

      session.user = token.user
      session.authorization = token.authorization
      return session
    },
  },

  pages: {
    signIn: "/auth/login",
  },
}
export {authOptions}

My next-auth.d.ts

import NextAuth from "next-auth";

declare module "next-auth" {
  interface Session {
    user: {
      id: number;
      email: string;
      name: string;
      status: string;
      avatar?:string;
    };

    authorization: {
      token: string;
      type: string;
      expiresAt: number
    };
  }
}

import { JWT } from "next-auth/jwt"

declare module "next-auth/jwt" {
  interface JWT {
    user: {
      id: number;
      email: string;
      name: string;
      status: string;
      avatar?:string;
    };

    authorization: {
      token: string;
      type: string;
      expiresAt: number
    };
  }
}

when the login is success i get the following response

  const { data: session } = useSession();
  console.log({ session });
{
    "user": {
        "id": 1,
        "name": "User One",
        "email": "[email protected]",
        "status": "active",
        "avatar": null
    },
    "expires": "2024-04-23T09:51:41.208Z",
    "authorization": {
        "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vYmVzc2VudGlhbHMudGVzdC9hcGkvYXV0aC9sb2dpbiIsImlhdCI6MTcxMTI3MzkwMSwiZXhwIjoxNzExMjc3NTAxLCJuYmYiOjE3MTEyNzM5MDEsImp0aSI6IlpzUjZyUHdHaHU1bVJVSEMiLCJzdWIiOiIxIiwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.nplynjW_PgzeAPyBnDZJI0vp3Wv9ehpAdQqME12mzsE",
        "type": "bearer",
        "expiresAt": 1711277501
    }
}

in the above session data expiresAt is sent by the external server where expires is generated by next auth.

I want to expire session (sign out user) when token time expires. How do i configure/tell next auth to watch expiresAt as token time instead of expires.

Upvotes: 0

Views: 1196

Answers (1)

Ahmet Firat Keler
Ahmet Firat Keler

Reputation: 4040

You asked "How do i configure/tell next auth to watch expiresAt as token time instead of expires?"

The Answer: You just can't.

Your server generated token and next-auth session do not work the same.

Balázs Orbán from the core team says

"The session expiry is not the same as a third party access token. next-auth rotates the session expiry, meaning whenever the client contacts the backend, it will update the session expiry date. (which is basically the cookie lifetime)

with other words, the session doesn't have a fixed/absolute expiry time as usually access tokens have.

If the user doesn't open the page for a while, the cookie will expire and will be removed automatically. so make sure the session expiry is always lower than your access token expiry date, if you cannot refresh the access token."

The rest of the discussion can be found on this link: https://github.com/nextauthjs/next-auth/discussions/2790

Of course, you can still terminate the user's session once your server generated token expires. But this is another question which I will not address here.

Upvotes: 0

Related Questions