0

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?

1 Answer 1

0

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.

4
  • Perfect! Is there a limit to how many api calls you can make in an allotted time? Aug 9, 2017 at 18:12
  • Yes, the limits are bound to your org, you need to go to Setup -> System overview, there on the right you can see the amount of API requests used vs the total available.
    – Alberto
    Aug 10, 2017 at 9:11
  • This seems more the password flow instead of the JWT from the question, right? I guess the issue is trying to avoid passing username password and token
    – manza
    Jan 30, 2020 at 6:25
  • OP never mentioned to login with JWT, simply the request returned the login page as a html document because the authentication failed. Authenticating a user with client id and secret of the connected app will solve the issue. The JWT authentication requires additional steps as described here: help.salesforce.com/…
    – Alberto
    Jan 30, 2020 at 9:04

You must log in to answer this question.

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