How to Debug OAuth Auth Code Login Flows

This is from the oauth clients perspective. Some piece of software is implementing a login with Google or Github or {socialPlatform}, and it’s not working.

Client and Authorization Server are terms found in the OAuth2 spec’s section on roles.

Errors on the Authorization Server

These are often in the form of an invalid_client error code. In these cases, the request never makes it back to the client application because the authorization server cannot authenticate the client.

Two main possiblities here:

  1. The OAuth client ID passed into the authorization url as client_id is wrong.
  2. The the redirect_uri passed into the authorization URL is wrong — could be that it’s not set and is required or it could be that it’s wrong.

In both cases it’s a good idea to check the source of those values in the client application. Is the client ID passed in via an environment variable? What is that value set to locally? Is the value updated in the secrets manager that powers production env variables?

Same story for redirect_uri: was it generated dynamically or passed in via an environment variable or other config? If it was generated, does the generated URL include a port or something that’s not set in the authorization server’s version?

OAuth redirect URIs are compared with simple string comparison, not URL parsing. Most authorization servers require them to be an exact match.

Errors Exchanging an Authorization Code for an Access Token

Assuming the client application receives a successful redirect back from the authorization server. At this point there’s no error parameter in the redirect and there is a code parameter. Something is going wrong exchanging that code for an access token.

The access token requests require the same client ID, and, in most cases, redirect URI as the authorization request. So validate those two are correct (see the section above).

For private clients — a server-side login flow — the other piece in the token request is the client_secret parameter. This is likely part of configuration or an environment variable, so verify it’s correct in those places: especially in a prod-like environment where the value may come from a secrets management system. Errors from a bad client secret should be invalid_client.

It’s possible to do an auth code login flow with proof key code exchange. This is most often used with public clients who cannot keep a client secret… secret. In those cases the client_secret would not be included in the request. This could be something like a mobile app or a client-side only JavaScript application.

When the PKCE piece fails the authorization server’s token endpoint should return an invalid_grant error. It’s possible that the code challenge sent with the original authentication request was computed incorrectly or the code verifier itself was not stored or otherwise corrupted — for client side apps this could mean local storage or cookies were cleared or something like that.