Solved

Customer Account API : Can't obtain access token "Multiple client credentials are provided."

DamienJ
Shopify Partner
2 1 0

Hello,


Firstly, to provide context to my project, I aim to develop a PHP application with Symfony that allows me to manage my store and customers in a "Headless".
Like to Hydrogen, I want my customers to be able to login using the 6-digit code login offered by Shopify.

I am using the Customer API to obtain an accessToken, so I installed the Headless application and configured it as "Confidential."
I also set up my callback URL in the Headless application.
To obtain the login form (with the 6-digit code), I use the URL: https://shopify.com/63XXXXXXX68/auth/oauth/authorize with the parameters described in the documentation.

Here is my code:

 

 

 

$url = sprintf(
    'https://shopify.com/%s/auth/oauth/authorize?scope=%s&client_id=%s&redirect_uri=%s&response_type=code&state=%s&nonce=%s&ui_locales=%s',
    '63XXXXXXX68',
    urlencode('openid email https://api.customers.com/auth/customer.graphql'),
    'shp_6958562d-XXXX-XXXX-XXXX-14c6cadacbf2',
    urlencode('https://xxxxxxxxx.ngrok.dev/auth/oauth/callback'),
    $this->generateState(),
    $this->generateNonce(),
    'fr'
);

 

 


I retrieve the "code" in my callback function, allowing me to execute the following request to obtain the accessToken.
I make a POST request to the following URL: https://shopify.com/63XXXXXXX68/auth/oauth/token, and in the body, I provide the parameters:

  • grant_type
  • client_id
  • code
  • redirect_uri

Here is my code:

 

 

 

$clientId = 'shp_6958562d-XXXX-XXXX-XXXX-14c6cadacbf2';
$clientSecret = 'a5604f7b8ae661db38cxxxxxxxxxxxxxxxxxxxxxxxxxxxx95e699362cbdb9597';

$code = $request->query->all()['code'];
$credentials = hash('sha256', $clientId . ':' . $clientSecret);

$response = $this->client->request(
    'POST',
    sprintf('https://shopify.com/%s/auth/oauth/token', '63XXXXXXX68'),
    [
        'headers' => [
            'content-type: application/x-www-form-urlencoded',
            'Authorization' => 'Basic ' . $credentials,
        ],
        'body' => [
            'grant_type' => 'authorization_code',
            'client_id' => $clientId,
            'code' => $code,
            'redirect_uri' => urlencode('https://xxxxxxxxx.ngrok.dev/auth/oauth/callback'),
        ],
    ],
);

 

 


In the header, I add the "Authorization" parameter with the value being the hash256 of the concatenation of the clientId and clientSecret keys provided by the Headless application.
Unfortunately, I encounter a 400 error with the following JSON response:

{"error":"invalid_request","error_description":"Multiple client credentials are provided."}

Thank you.

Accepted Solution (1)

DamienJ
Shopify Partner
2 1 0

This is an accepted solution.

After conducting research, I found a solution.
In the documentation (https://shopify.dev/docs/api/customer#step-obtain-access-token), the "Authorization" header seems to be unnecessary.
Instead, in the body of the "accessToken" request, I need to include the "client_secret" like this:

 

 

        $response = $this->client->request(
            'POST',
            sprintf('https://shopify.com/%s/auth/oauth/token', $shopify['shop_id']),
            [
                'headers' => [
                    'Content-Type' => 'application/x-www-form-urlencoded',
                ],
                'body' => [
                    'grant_type' => 'authorization_code',
                    'client_id' => $clientId,
                    'client_secret' => $clientSecret,
                    'code' => $code,
                    'redirect_uri' => 'https://lighthouse.ngrok.dev/auth/oauth/callback',
                ],
            ],
        );

 


And I removed the urlencode in the redirect_uri in the 2 requests.

View solution in original post

Reply 1 (1)

DamienJ
Shopify Partner
2 1 0

This is an accepted solution.

After conducting research, I found a solution.
In the documentation (https://shopify.dev/docs/api/customer#step-obtain-access-token), the "Authorization" header seems to be unnecessary.
Instead, in the body of the "accessToken" request, I need to include the "client_secret" like this:

 

 

        $response = $this->client->request(
            'POST',
            sprintf('https://shopify.com/%s/auth/oauth/token', $shopify['shop_id']),
            [
                'headers' => [
                    'Content-Type' => 'application/x-www-form-urlencoded',
                ],
                'body' => [
                    'grant_type' => 'authorization_code',
                    'client_id' => $clientId,
                    'client_secret' => $clientSecret,
                    'code' => $code,
                    'redirect_uri' => 'https://lighthouse.ngrok.dev/auth/oauth/callback',
                ],
            ],
        );

 


And I removed the urlencode in the redirect_uri in the 2 requests.