[SalesForce] Authorization PHP Curl returns Login page instead of token

I am trying to use PHP curl to authenticate my app's user, but instead of authenticating with OAuth it returns the actual html login form as a response. Why? I don't want to redirect the user over and over every time the need to re-authenticate.

$params = "/authorize?response_type=code=&client_id=" . $clientAuth
        . "&client_secret=" . $clientSec
        . "&redirect_uri=" . $callBack;

$auth_url = $instance_url;

$headers = [
    'Content-type: application/x-www-form-urlencoded',
];

$ch = curl_init();
curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
curl_setopt( $ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY );
curl_setopt( $ch, CURLOPT_USERAGENT, $agent );
curl_setopt( $ch, CURLOPT_URL, $auth_url );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_POST, count( $params ) );
curl_setopt( $ch, CURLOPT_POSTFIELDS, urlencode( $params ) );

$json_response = curl_exec( $ch );
$status = curl_getinfo( $ch, CURLINFO_HTTP_CODE );

echo '<pre>';
print_r( $json_response );
print_r( $status );

I am not sure why it only returns the form instead of performing the process as like it does if I use the browser to send the user there.

What am I doing to cause this issue?

Best Answer

if you are getting the Login page, it means your request is not authorized properly. I'm also authenticating to the ERP using OAuth2, if the authentication works fine, I get the access token and the instance url from the server, then I perform my API request as an authenticated user.

Here is the code I use:

private static function getAccess()
    {
        $curl = curl_init();
        curl_setopt_array(
            $curl,
            array(
                CURLOPT_RETURNTRANSFER => TRUE,
                CURLOPT_URL            => LOGIN_URI . "/services/oauth2/token",
                CURLOPT_POST           => TRUE,
                CURLOPT_POSTFIELDS     => http_build_query(
                    array(
                        'grant_type'    => GRANT_TYPE,
                        'client_id'     => CLIENT_ID,
                        'client_secret' => CLIENT_SECRET,
                        'username'      => END_USERNAME,
                        'password'      => END_PASSWORD . TOKEN
                    )
                )
            )
        );

        $response = json_decode(curl_exec($curl));
        curl_close($curl);

        $access_token = (isset($response->access_token) && $response->access_token != "") ? $response->access_token : die("Error - access token missing from response!");
        $instance_url = (isset($response->instance_url) && $response->instance_url != "") ? $response->instance_url : die("Error - instance URL missing from response!");

        return array(
            "accessToken" => $access_token,
            "instanceUrl" => $instance_url
        );
    }

Where LOGIN_URI is the instance URL of your org (https://YOURORG.my.salesforce.com), GRANT_TYPE is "password", CLIENT_ID and CLIENT_SECRET are the alphanumeric strings you've got from your org, END_USERNAME is the username you are using to authenticate in your org, END_PASSWORD is the user's password, TOKEN is the user's personal token.

Once your user get authorized, you receive a token from the server and you can perform any API request using cURL:

private static function exec($url)
    {
        $credentials = self::getAccess();

        $curl = curl_init($credentials['instanceUrl'].$url);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: OAuth ".$credentials['accessToken']));

        $json_response = curl_exec($curl);
        curl_close($curl);

        return $json_response;
    }

In this case, you only need to authorize once your user to access the org via APIs, every other request you make you just need to use the token you've received from the server.

Related Topic