According to Google’s docs on OAuth, the server application gets
refresh_token from Google (on exchanging the auth code) only if the original redirection request to Google contains the param
access_type with value
offline (documentation link).
But this is only for the first time a user authenticates with your app. If for some reason your flow takes the user through the authentication flow again without having changed anything (user’s Google account, permissions required, etc. Haven’t tested with changed permissions yet but definitely happens when permissions also remain the same) then when you exchange auth code for tokens from Google, the Google servers don’t return the
refresh_token this second time.
This is based on anecdotal observation, and I couldn’t find any such mention in their documentation. An answer on Stack Overflow confirmed for me that it wasn’t something misconfigured on my end 😅.
A “solution” for this could be to always specify the param
prompt with a value of
consent in the original redirect request where we send user to Google’s flow.