Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google OAuth Always Showing Consent Screen

I'm building an installed application that will have features requiring the Google Drive REST API using Qt and C++. I understand Qt is now releasing new libraries to support OAuth flows but let's assume I'm a student and learning to use OAuth at this layer is a requirement for this project.

In my application, I have a working OAuth flow for installed applications that ends with an Access Token and Refresh Token being stored using QSettings (I'm open to input on whether this is a disastrously bad idea too). The application requires no authentication/login for its own sake/data, but it does need authentication to Google for calling API's using an Access Token. This application has no associated web backend being hosted; its simple and should be deployable completely locally (I've written and included a simple TCP server that will receive the authorization redirect_uri and will run and close when called from within the application).

As such, I'm curious about the best way to make sure that, when a user opens my application and wants to use the Google Drive features, they are appropriately authenticated on Google's end. Say, if I maintain an access token in the registry, and this access token is granted per-user/per-application basis (right?), then how can I make sure only the user the token belongs to is able to make calls to the API with it?

Here's my understanding and approach; feel free to correct me or educate me if I've got the wrong interpretation.

If an Access Token is found, perform the following:

  1. Open a browser page to a Google login domain and have the user authenticate there (this could prohibit a user from being able to use a cached login session that would have access to a token they otherwise shouldn't have access to)
  2. If user has correctly authenticated with a Google account, return control to the application and make a test call to an API using the stored token.
  3. If the call fails (responds with an invalid_credentials) I should be able to be sure its because the access token has expired and the application will go through the flow to renew an Access Token from a Refresh Token.

If no Access Token is initially found:

  1. Start a normal OAuth installed application flow
  2. Get the tokens and store them so that when the user opens the application next time the former procedure is used

My issue then is the first two steps if the Access Token is found. Nominally this could be done by the typical OAuth flow but it appears that when using a localhost as the redirect uri, Google will always prompt for consent, regardless of settings for prompt and access_type authorization query parameters.

What can be done to accomplish these first two steps in a way that my application can control (i.e. not a solution that relies on a backend server being hosted somewhere)?

If this question is too open-ended for SO requirements I can make some more restrictions/assumptions to limit the problem domain but I'd rather not do that yet in case I unknowingly rope off a good viable solution.

Thanks for reading! Sorry if its a verbose; I wanted to ensure my problem domain was fully fleshed out!

like image 672
Nathan Blair Avatar asked Oct 28 '25 01:10

Nathan Blair


1 Answers

If you are using an installed application, I wouldn't recommend using or storing refresh tokens. Storing refresh tokens on the client side means that if an intruder gains access to the client's application, they have infinite access to the user's application without ever having to enter the user's credentials. If you do insist on having a refresh token, ensure you follow the Google's installed app flow, with the code_verifier parameter included in your requests.

If the access token is found, you should try to verify it, and if verified then use it at the google api, otherwise force the user to login again (or refresh it if you chose to still use refresh tokens).

If no access token is found, your flow sounds fine.

A few notes on loggin in with Google:

  1. Google will only return a refresh token if you specify access_type=offline in your auth request.
  2. Google will only return a refresh token on the user's first authorization request, unless you always specify prompt=consent in your query params.
  3. In my experience, when leaving out the prompt query param, the user is not prompted for their consent again. If they are logged in to google, you will get a new access token, but no refresh token, unless you have prompt=consent.
  4. I think the idea is you use prompt=consent if you have no record of the user ever using your application. Otherwise if they have used it before, you may prefer to use prompt=select_account to allow the user to select which account he wants to use in case he has more then one, or you can just use prompt=none.

This is just my understanding of it all.

like image 129
Panda Avatar answered Oct 31 '25 02:10

Panda