I previously posted the following question in the GitHub discussions for NextAuth but did not receive any responses, so I am raising it here as well (https://github.com/nextauthjs/next-auth/discussions/11819):
I’m using NextAuth.js with the Google provider in my application. By default, I only request the profile and email scopes, which works well for normal login. Here's my provider configuration:
const authOptions: AuthOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID || '',
clientSecret: process.env.GOOGLE_CLIENT_SECRET || '',
authorization: {
params: {
scope: 'profile email'
}
}
})
]
};
I have a section in my application that requires access to the user's Gmail (to read and display their emails). I don’t want to force users to grant Gmail permissions during the initial login. Instead, I want to add a button in that specific section so that users can grant Gmail access only when they need it.
For the current session, the following code works to request Gmail permissions dynamically:
function requestGmailPermissions() {
signIn('google', undefined, { scope: 'profile email https://www.googleapis.com/auth/gmail.readonly', login_hint: session?.user?.email || '' });
}
However, the issue is that once the user logs out and logs back in, the Gmail permission is "lost," and they have to press the button again. I assume this happens because my Google provider setup doesn’t request the Gmail permission by default, so it doesn’t persist across sessions.
My question: Is there a way to persist the Gmail permission across logins so that the user doesn’t have to press the button and re-grant the permission every time they log in?
Thanks in advance for any help!
Related to: How to update the existing account scope incrementally How to add additional OAuth Scopes / Permissions to existing account
These issues are similar to mine, but neither provides a solution for ensuring that the Gmail permission persists across logins. Although the Gmail permission is successfully granted and appears under "https://myaccount.google.com/connections" for my application (indicating that it’s set permanently), I lose access to it after the user logs out and logs back in. I believe this happens because the Gmail permission isn't included in my Google provider's scope definition by default. I’m looking for a way to persist this permission without the user needing to re-grant it after every login.
I’ve implemented a workaround where users log in without Gmail permissions initially, and then they grant the permission every time after logging in, using a button in the relevant section of my application. This works, but it forces users to re-grant the permission after every login, which is not ideal.
I also tried a solution where I save the state in my database to track whether the user has granted the Gmail permission before. If so, I automatically initiate a sign-in with the additional permissions on the relevant page. However, this approach causes the page to reload entirely, refreshing all states and reloading the context data, which disrupts the user experience.
Additionally, the token expires after an hour, and I need to initiate the sign-in process again to get a new access token. I considered requesting a refresh token using this configuration:
authorization: {
params: {
prompt: "consent",
access_type: "offline",
response_type: "code"
}
}
But this forces the user to accept the permissions on an additional page, which means an automatic sign-in in the background is no longer feasible.