1

I'm trying to implement a web flow authentication process using php; so far, I've created the necessary index.php file which is used to get the first code:

// Generate a random code verifier
$codeVerifier = rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');

// Create code challenge from the verifier using SHA-256
$codeChallenge = rtrim(strtr(base64_encode(hash('sha256', $codeVerifier, true)), '+/', '-_'), '=');

// Set your Salesforce OAuth parameters
$clientId = $CLIENT_ID;
$redirectUri = 'https://mydomain.dev/redirect.php';
$scope = 'api';

// Construct the authorization URL with PKCE parameters
$authorizationUrl = sprintf(
    'https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s&code_challenge_method=S256&code_challenge=%s',
    $clientId,
    urlencode($redirectUri),
    urlencode($scope),
    $codeChallenge
);

header('Location: ' . $authorizationUrl);
exit;

The above code goes to salesforce, and back to my site and the redirect.php page with the code as a parameter; a code which I will use to retrieve the access/refresh tokens.

The redirect.php is the following:

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://login.salesforce.com/services/oauth2/token',
    CURLOPT_ENCODING => '',
    CURLOPT_POST => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => array(
        'code' => $_GET["code"],
        'grant_type' => 'authorization_code',
        'client_id' => $CLIENT_ID,
        'client_secret' => $CLIENT_SECRET,
        'redirect_uri' => 'https://mydomain.dev/redirect.php',
    ),
));

$response = curl_exec($curl);

curl_close($curl);

echo "<pre>" . print_r($response, true) . "</pre>";

Theoretically, at the end, I should end up with a json object containing both access and refresh tokens.

Instead, I'm ending up with the following error:

{"error":"invalid_grant","error_description":"invalid code verifier"}

PS: I am not interested in a simple username/password authentication, because I want to store both access/refresh tokens for a server side process.

Can you help me guys, to understand what am I doing wrong here?

Thank you!

2

1 Answer 1

0

If you specify a code_challenge in your token request, you must include a code_verifier parameter when requesting the access and refresh tokens. Either (a) do not use code_challenge, or (b) make sure you specify the same value that was in the code_challenge parameter from the first token request. You can read more about the parameters in the documentation. If you want to use the code challenge, you can store the randomly generated code in a PHP session value in step 1, then use it in step 2.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .