Anton Baranenko
Anton Baranenko

Reputation: 644

TOKEN endpoint returns invalid_client without client secret

I am having difficulty with the authorization code flow in Amazon Cognito. The workflow that I am trying to build is the following:

  1. A user authenticates with the built-in Cognito UI.
  2. Cognito redirects back with the authorization code.
  3. I send the code to server where it's exchanged for tokens using /oauth2/token endpoint.

I have created a client without client secret. I authenticate using the Cognito UI, get back the code, then send the following with Postman:

URL: https://MY-DOMAIN/oauth2/token
Method: POST
Headers: 
Content-Type: application/x-www-form-urlencoded
Body:
  grant_type=authorization_code&
  client_id=<my-client-id>&
  code=<code-from-cognito-ui>&
  redirect_uri=<my-redirect-url>

I do not use Authorization since there's no client secret.

In return I receive:

Code: 400
Body: { "error": "invalid_client" }

The app client is allowed authorization code grant in the AWS Cognito console.

Upvotes: 41

Views: 34622

Answers (7)

user21253405
user21253405

Reputation: 51

I was having a similar issue that was resolved by setting Client Authentication from the default "send as basic Auth header" to "Send client credentials in body".

Upvotes: 5

RishiH
RishiH

Reputation: 1

I had same situation: Code: 400 Body: { "error": "invalid_client" } Like other friends mentioned, App client created with client_secret need client_secret in API call then it works

Upvotes: 0

YasirAzgar
YasirAzgar

Reputation: 1453

Does not seem to be mentioned anywhere in the docs though, If you have created the client app with client_secret you should add the client_secret to the params for it to work.

curl -X POST \
'https://<Cognito User Pool Domain>/oauth2/token?
grant_type=authorization_code&
code=8a24d2df-07b9-41e1-bb5c-c269e87838df&
redirect_uri=http://localhost&
client_secret=xcxxxs2r234XXXXXX&
client_id=55pb79dl8gm0i1ho9hdrXXXXXX' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Content-Type: application/x-www-form-urlencoded'

Or you need to create the app with "generate client_secret" = false. Also By default, user pools generates a client secret for your app.

Upvotes: 50

h-kippo
h-kippo

Reputation: 459

In the comments of the question you mention:

repeated the same steps after some while and they worked.

I stumbled upon the same or similar problem. The solution for me was not to use a previously signed-in session. I had to sign out or open an incognito/private browser session and sign in again to resolve the issue.

All the parameters in the question are valid according to the documentation.

Upvotes: 1

Taylor Buckner
Taylor Buckner

Reputation: 160

I would comment on the other solutions, but not enough rep yet.

As some additional information to anyone who comes across this issue in the future:

Not only is the Authorization header not required... it's Not Allowed.

Saying "Not Required" led me to believe it was optional. In fact, if you pass that along the request, I found that the response would often be as described by OP:

Code: 400
Body: { "error": "invalid_client" }

Upvotes: 10

Ashish Kumar
Ashish Kumar

Reputation: 249

The problem is with Authorization header.

When using client without client secret Authorization header is not required.

Example:

curl -X POST \
'https://<Cognito User Pool Domain>/oauth2/token?
grant_type=authorization_code&
code=8a24d2df-07b9-41e1-bb5c-c269e87838df&
redirect_uri=http://localhost&
client_id=55pb79dl8gm0i1ho9hdrXXXXXX&scope=openid+email' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Content-Type: application/x-www-form-urlencoded'

Upvotes: 23

Chris
Chris

Reputation: 1428

I had a similar issue when working with Cognito on iOS (not amplify) but I figured it out that I needed to actually send nil (for swift).

I'm not sure if that will help your situation but here's what I have in Swift:

@objc func config(_ call: CAPPluginCall) {
    let appClientId = "myclientid";
    let scopes = Set<String>(["openid", "email"]);
    let signInRedirectUri = "com.myappurl://signin";
    let signOutRedirectUri = "com.myappurl://signout";
    let webDomain = "https://[myappdomain].auth.us-east-2.amazoncognito.com";

    // NOTICE my nil here for appClientSecret, if I used "" it would throw the error you are seeing
    let config = AWSCognitoAuthConfiguration(appClientId: appClientId, appClientSecret: nil, scopes: scopes, signInRedirectUri: signInRedirectUri, signOutRedirectUri: signOutRedirectUri, webDomain: webDomain);

    AWSCognitoAuth.registerCognitoAuth(with: config, forKey: "AWSCognito")
    call.resolve()
}

It may not answer the situation you have exactly but this is what worked for me to remove the horrible error invalid_client.

Upvotes: 1

Related Questions