jwt 回调中的下一个身份验证注销

ama*_*ter 7 javascript reactjs next.js next-auth

如果用户在应用程序升级之间登录到应用程序,那么我想在用户下次访问时注销该用户。

我从 jwt/session 中提取版本并将package.json其存储在 jwt/session 中,以便比较用户通过哪个版本进行身份验证以及现在正在运行哪个版本。

// pages/api/auth/[nextauth].ts
const version = require('../../../package.json').version
import NextAuth from 'next-auth'
import { signOut } from 'next-auth/react'

export default NextAuth({
  providers: [ /*...*/ ],
  session: { strategy: 'jwt' },
  callbacks: {
    async jwt(props) {
      const { token, user, account } = props
      const isSignIn = user?.username ? true :false
      if(isSignIn) {
        token.version = version
        // ...
      }
      if (token?.version !== version) {
        await signOut()
        return {}
      }
      return token
    },
    // ...
  }
})
Run Code Online (Sandbox Code Playgroud)

这有效,但它抛出一个错误

https://next-auth.js.org/errors#jwt_session_error window is not defined {
  message: 'window is not defined',
  stack: ...
  name: 'ReferenceError
}
Run Code Online (Sandbox Code Playgroud)

我知道抛出错误是因为我在服务器端调用该函数,而该函数本应是浏览器端函数,因此未定义signOut错误。window

我还能如何调用该signOut函数而不尝试使用浏览器端调用(包括对 的引用)window

kwa*_*ert 15

根据我收集的信息,您不能在服务器端使用退出,但这是我在我的案例中使用的技巧。相反,尝试从服务器端注销会返回错误代码。

const version = require('../../../package.json').version
import NextAuth from 'next-auth'
import { signOut } from 'next-auth/react'

export default NextAuth({
  providers: [ /*...*/ ],
  session: { strategy: 'jwt' },
  callbacks: {
    async jwt(props) {
      const { token, user, account } = props
      const isSignIn = user?.username ? true :false
      if(isSignIn) {
        token.version = version
        // ...
      }
      if (token?.version !== version) {
        return {
        // You can ignore this if you don't need the previous data
         ...token,
        // Return an error code 
         error: "invalid-version",
        }
      }
      return token
    },
    // ...
  }
})
Run Code Online (Sandbox Code Playgroud)

围绕安全路由创建包装器。您也可以在通用布局中执行此操作。

export const Auth = ({children}) => {
  const { data: sessionData } = useSession();
  const router = useRouter();

  useEffect(() => {
    // check if the error has occurred
    if (sessionData?.user.error === "invalid-version") {
        // Sign out here
        signOut();
    }
  }, [sessionData?.user.error, router]);

  return (
    <>{children}</>
  )
}
Run Code Online (Sandbox Code Playgroud)