如何在nextjs auth中1小时后自动过期会话?

nx7onnlm  于 2023-04-20  发布在  其他
关注(0)|答案(1)|浏览(122)

我正在尝试在1小时后自动终止会话,但没有成功。
目前,我正在尝试设置一个自定义会话。基于后端JWT令牌的会话回调中过期:

async session({ session, token }) {
            const userId = token.sub

            const user = [...logic to populate the 'user' variable]

            session.accessToken = token.accessToken as string
            const payload: { exp: number } = jwt_decode(session.accessToken as string)

            session.user = user
            session.expires = new Date(payload.exp * 1000).toISOString()
            return session
        },

如果我在登录后保持浏览器窗口打开,1小时后用户似乎断开连接,因为你可以看到从端点“/API/auth/session”接收的对象是空的,然而,当重新加载页面时,会话会重新填充过去的expires属性。

{
    "user":{},
    "expires":"2022-05-19T07:21:07.000Z",
    "accessToken":"ACCESS_TOKEN_GOES_HERE"}

PS:“user”和“accessToken”属性已正确填充。出于安全原因,我省略了它。

sczxawaw

sczxawaw1#

我也有同样的要求,我已经能够实现这一点,在用户对象中设置一个不同的键(因为我也需要在用户会话中),而不是“到期”,因为nextAuth将自动旋转expires键的值,当你刷新页面。
[...nextauth].ts文件的NextAuth session回调中设置会话过期值,如下所示。

callbacks: {
  ....
  async session({ session, token }) {
    session.user = token.user;

    if (!session.user.session_expiry) {
      // set expiration to 12 hours for now
      const exp = new Date(new Date().getTime() + 12*60*60*1000).toISOString(); 
      session.user.session_expiry = exp;
    }

    return session;
  },
}
...

在您的客户端代码中,您将需要检查此过期并调用nextAuth的signout方法。

const { status, data: sessionData } = useSession();

const { user: { session_expiry: sessionExpiry = null } = {} } =
  sessionData || {};

useEffect(() => {
  const isSiteSessionExpired = sessionExpiry || new Date(sessionExpiry) < new Date();
  if (status === "authenticated" && isSiteSessionExpired) {
     signOut();
  }
}, [sessionExpiry, status]);

如果会话已过期,这将强制用户注销。
额外的好处:如果你使用的是typescript,使用下面的代码来检查session_expiry变量的类型。

import { type DefaultSession } from "next-auth";

type UserWithSessionExpiry = {
  session_expiry?: string;
} & DefaultSession["user"];

declare module "next-auth" {
  interface Session {
    user: UserWithSessionExpiry;
  }
}

相关问题