If a user is signed into the app between app upgrades, then I want to sign out the user the next time they visit.
I am pulling the version in from the package.json
and storing it in the jwt/session to have for comparison of which version the user authenticated from and what version is now running.
// 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
},
// ...
}
})
This works, but it is throwing an error
https://next-auth.js.org/errors#jwt_session_error window is not defined {
message: 'window is not defined',
stack:
name: 'ReferenceError
}
I know the error is throwing because I am calling the signOut
function on the server side when it is meant to be a browser side function hence the error for window
is not defined.
How else can I call the signOut
function without it trying to use the browser side call including the reference to window
?
Advertisement
Answer
You can’t use signOut on sever side from what I gathered, but here is a trick I used in my case. Instead trying signOut from the server side return an error code.
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
},
// ...
}
})
Create a wrapper around the secured routes. you can do this in a common layout too.
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}</>
)
}