Ad

OAuth2 Callback - Identify User?

- 1 answer

The question: when I authenticate a user using oauth2 (initiated from my server), how do I get the initial user id from the oauth2 callback so I can map it back to the initial auth request on my server?

Contex:

I'm working on a web app where I need to ask user to grant access to their google calendar.

Consider the oauth flow:

web client (sends request to) -> backend (sends oauth request to) -> google (grants access) -> backend (how do I know the user in this step to store the refresh_token?)

Here is more details default flow:

  • user logs in to my web app (client)
  • the web app asks the user to start oauth2 flow (client)
  • that sends the "start auth flow" request to my backend (backend)
  • on the backend I send oauth request to google like below:
const authUrl = new google.auth.OAuth2(clientId, secret, redirectUrl)).generateAuthUrl(options)
res.redirect(authUrl)
  • this redirects user to the google consent page. (google)
  • Once the user granted the permission, they are redirected back to the url specified in OAuth2 client (backend, my "callback" endpoint)
  • at this point I need to save the refresh_token to the user's database location. (backend)

So how do I understand from the "callback" that this is still the same user who started the flow?

Ad

Answer

It appeared that there is a parameter called state that one can use to pass specific data and google will return it back. This solves my question since I can pass user id or my session token as state and read it in the callback.

From the doc:

state Recommended.

Specifies any string value that your application uses to maintain state between your authorization request and the authorization server's response. The server returns the exact value that you send as a name=value pair in the hash (#) fragment of the redirect_uri after the user consents to or denies your application's access request.

In case of nodejs google oauth2 library that may look like this:

oauth2ClientGlobal.generateAuthUrl({
            access_type: 'offline',
            scope: this.scopes(),
            state: base64UserId // <- google will return this param back
        });
Ad
source: stackoverflow.com
Ad