NextAuth.js is a popular authentication library for Next.js applications. It makes it easy to set up authentication providers and handle user sessions. However, one challenge that developers often face is ensuring that OAuth tokens remain fresh. This article outlines how to handle token refresh with NextAuth.js and Prisma.
Overview
When integrating OAuth providers like Google or Discord, it’s essential to handle token refresh to ensure that the tokens remain valid. This is particularly important for scenarios where your application needs to make authenticated requests to third-party APIs on behalf of the user.
While doing this with Google you might get the following error.
401 Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential.
In this guide, we’ll look at how to handle token refresh using the signIn
and signOut
events provided by NextAuth.js, and how to update the token information in the database using Prisma.
Prerequisites
- A Next.js application with NextAuth.js and Prisma set up.
- OAuth set up with a provider like Google or Discord.
Updating Tokens on Sign-In
When a user signs in, we can use the signIn
event to update the token information in the database. This is where you add the code snippet for handling the sign-in event.
export const authOptions: NextAuthOptions = {
callbacks: {
// ...other callbacks
},
events: {
signIn: async (message) => {
console.log("signIn", JSON.stringify(message, null, 2));
const { account, user } = message;
const { access_token, refresh_token, expires_at } = account!;
await prisma.account.updateMany({
data: {
access_token,
refresh_token,
expires_at,
},
where: {
AND: [
{
userId: user.id,
provider: "google",
},
],
},
});
console.log(`Added user account with ID: ${user.id}`);
},
// ...other events
},
// ...other options
};
Clearing Tokens on Sign-Out
Similarly, when a user signs out, we may want to clear the token information from the database. This section will provide the code snippet for handling the sign-out event.
events: {
// ...other events
signOut: async (message) => {
console.log("signOut", JSON.stringify(message, null, 2));
const { userId } = message.session as unknown as { userId: string };
try {
await prisma.account.updateMany({
data: {
access_token: null,
refresh_token: null,
expires_at: null,
},
where: {
AND: [
{
userId: userId,
provider: "google",
},
],
},
});
console.log(`Deleted user account with ID: ${userId}`);
} catch (error) {
console.error(`Failed to delete user account with ID: ${userId}`, error);
}
},
},
Conclusion
Handling token refresh is crucial for maintaining a smooth user experience and ensuring that your application can continue to interact with third-party services on the user’s behalf. By leveraging the signIn
and signOut
events provided by NextAuth.js, and using Prisma to interact with your database, you can ensure that your OAuth tokens remain fresh and functional.
If you're a founder or CEO eager to move faster and seek tailored strategies for your unique challenges, don't navigate this journey alone. Reach out to me. Together, we can dissect, refine, and optimize your enterprise's trajectory to withstand the tests of time and innovation. Let's make your vision not just a goal, but an impending reality.
I have limited open hours. Book Appointment