You get an invalid client_id error

Admittedly, the word “client” seems to be applied to pretty much everything in the OAuth/OIDC world: public clients, confidential clients, login clients, application clients, configuration clients, you name it. With all that in mind, it almost seems inevitable that someday you’ll have an authorization request that fails with the following error:

img

Obviously you specified an invalid client ID. But what would a valid client ID look like?

To answer that question, let’s take a look at a typical authorization request and at the client_id parameter:

https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/login/authorize
  ?client_id=a123ef65-83dc-4094-a09a-76e1bec424e7
   &redirect_uri=https://wacky-harmonious-bike.dev.or.janrain.com/redirect_uri
   &scope=openid
   &code_challenge=-xY2YBrATwwfNo2lgk04WjSGqcLF1b2YXwFDG7er5QU
   &code_challenge_method=S256
   &response_type=code
   &state=nzMIwYSkkwKZeRsdW3nQ-KwNIqOWpyvG8ZoHcjlU3bE

In an authorization request, the client_id parameter must be set to the ID of an OpenID Connect login client. When troubleshooting an invalid client ID error, a good place to start is to look at the authorization request and see if the client ID is formatted as a UUID (Universally Unique Identifier). If it is, then you’re likely dealing with an OIDC client of some kind. However, you might see a client_id similar to this:

https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/login/authorize
   ?client_id= u74hp2xa4u75dq9s6wv8yyb28wkkux7m
   &redirect_uri=https://wacky-harmonious-bike.dev.or.janrain.com/redirect_uri
   &scope=openid
   &code_challenge=-xY2YBrATwwfNo2lgk04WjSGqcLF1b2YXwFDG7er5QU
   &code_challenge_method=S256
   &response_type=code
   &state=nzMIwYSkkwKZeRsdW3nQ-KwNIqOWpyvG8ZoHcjlU3bE

The specified client ID – u74hp2xa4u75dq9s6wv8yyb28wkkux7m – is not a UUID; that means this ID is probably pointing to your application client instead of your OIDC login client. Put the ID of the OIDC login client in there and see what happens.

The other thing you can (and should) do is take a peek at all your OIDC clients. Admittedly, you might have a mixture of OIDC client types: public clients, confidential clients, configuration clients, etc. However, a an OIDC login client (at least for the purposes of Hosted Login) will always:

  • Have its type set to public.
  • Have an associated application_client.

For example, the property values for an OIDC login client will look similar to this:

{
   "id": "a123ef65-83dc-4094-a09a-76e1bec424e7",
   "name": "New Public Client",
   "redirectURIs": [
       "http://127.0.0.1",
       "https://localhost:3001/redirect_uri",
       "https://wacky-harmonious-bike.dev.or.janrain.com/redirect_uri",
       "https://openidconnect.net/callback",
       "https://identitydocs.akamai.com"
   ],
   "loginPolicy": "ad2cad34-e06f-463e-a43f-b5c8af0ee965",
   "tokenPolicy": "a7f902b3-6e63-4f60-87a6-6cf5a1bc8ff4",
    "type": "public",
    "_links": {
       "self": {
           "href": "/config/e0a70b4f-1eef-4856-bcdb-f050fee66aae/clients/a123ef65-83dc-4094-a09a-76e1bec424e7"
       },
        "application_client": {
            "href": "/config/79y4mqf2rt3bxs378kw5479xdu/clients/u74hp2xa4u75dq9s6wv8yyb28wkkux7m"
        }
    }
}

Try using the value of the id property in your authorization request and see what happens.

📘

Keep in mind that you might have multiple OIDC login clients. That simply means that you might have to try a few different IDs before you find the exact login client you’re looking for.

Incidentally, you must also specify the client ID when exchanging an authorization code for an access token:

curl 'https://v1.api.us.janrain.com/e0a70b4f-1eef-4856-bcdb-f050fee66aae/login/token' \
    -d 'grant_type=authorization_code' \
    -d 'code=p_mTpmKWN2GyG4Fx' \
    -d 'redirect_uri=https://wacky-harmonious-bike.dev.or.janrain.com/redirect_uri' \
    -d 'client_id=a123ef65-83dc-4094-a09a-76e1bec424e7' \
    -d 'code_verifier=OXb2Cj8ohu2XIfcM2AtqpvseLp-xJwBIFeJHw4BSGMU'

Not too surprisingly, the client_id used in the token exchange call must match the client_id used in the authorization request. If it doesn’t, you’ll be authenticated, but you won’t be issued an access token.