parse-community / parse-php-sdk

The PHP SDK for Parse Platform
https://parseplatform.org/
Other
811 stars 346 forks source link

REST API not working with PHP #412

Closed MrMegamind closed 6 years ago

MrMegamind commented 6 years ago

I am integrating REST API using PHP but I always get Unauthorized error.

I have verified the credentials and they appear perfectly fine

PHP Code:

    ParseClient::initialize( $this->parse_app_id, $this->parse_rest_key, $this->parse_master_key);
    ParseClient::setServerURL('https://parseapi.back4app.com', '/');

    $health = ParseClient::getServerHealth();
    if($health['status'] === 200) {
        echo "everything looks good!";
    }
    print_r($health);

This is verbos output of cURL

< HTTP/1.1 401 Unauthorized < Access-Control-Allow-Credentials: true < Access-Control-Allow-Headers: DNT, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, X-Application-ID, X-Access-Token, X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Job-Status-Id, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-CSRF-Token < Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS < Access-Control-Allow-Origin: * < Content-Type: application/json; charset=utf-8 < Date: Fri, 28 Sep 2018 12:57:05 GMT < ETag: W/"18-gH7/fIZxPCVRh6TuPVNAgHt/40I" < Server: nginx < X-Content-Type-Options: nosniff < X-Frame-Options: SAMEORIGIN < X-Powered-By: Express < X-XSS-Protection: 1; mode=block; < Content-Length: 24 < Connection: keep-alive <

acinader commented 6 years ago

@MrMegamind this is a configuration issue, not an issue with the sdk. I think that the ParseClient::setServerURL might be incorrect? You may also be able to get support from back4app?

MrMegamind commented 6 years ago

I added following code in ParseCurl.php file at around line 48

    $this->setOption(CURLOPT_HTTPHEADER,array("X-Parse-Application-Id: xxx", "X-Parse-REST-API-Key: xxx"));

and then it started working, which means the SDK has issues of not setting the headers when we initialize

acinader commented 6 years ago

Do you mean around line 480?

Can you step through ParseClient::_request() and see why the header isn't getting set?

Can you double verify that $this->parse_app_id, $this->parse_rest_key, $this->parse_master_key are definately set in your initialization?

What version of the SDK are you using?

acinader commented 6 years ago

I'm gonna close this for now. We can re-open if necessary.

git-elliot commented 5 years ago

I'm facing the same issue. I'm using back4app and here is my initialization code.

<?php

require 'vendor/autoload.php';
use Parse\ParseClient;

$app_id = "FAxjcqLe7t2zxeOtxxxxxxxxxxx";
$rest_key = "FuiOPvWei8Scwxxxxxxxxxxxxxxxxx";
$master_key = 'IdN0psRjfv9bJNPxxxxxxxxxxxxxxx";

ParseClient::initialize( $app_id, $rest_key, $master_key );
ParseClient::setServerURL('https://parseapi.back4app.com/','/');

$health = ParseClient::getServerHealth();
echo("health check started..<br>");

echo(json_encode($health));

if($health['status'] === 200) {
    // everything looks good!
    echo("<br>health is good");
}else{
    echo("<br>health is not good");
}

echo("<br>health finished..");
?>

here is the output i'm getting.

health check started..
{"status":401,"response":{"error":"unauthorized"}}
health is not good
health finished..

I don't know what should be the mount point for parse in back4app. But I've checked the sdk it allows to mount at root so I passed the "/", here is the evidence.

public static function setServerURL($serverURL, $mountPath)
    {
        if (!$serverURL) {
            throw new Exception('Invalid Server URL.');
        }
        if (!$mountPath) {
            throw new Exception('Invalid Mount Path.');
        }

        self::$serverURL = rtrim($serverURL, '/');
        self::$mountPath = trim($mountPath, '/') . '/';

        // check if mount path is root
        if (self::$mountPath == "/") {
            // root path should have no mount path
            self::$mountPath = "";
        }
    }

It checks at the end for the mount point as root. I'm using PHP 7.2, and installed sdk from composer.

Note : curl is working fine using php and back4app. The problem is in parse sdk.

git-elliot commented 5 years ago

For those who want workaround is what @MrMegamind said to do. Add these lines inside the exec() function of ParseCurl.php, before the curl_exec() function.

curl_setopt($this->curl, CURLOPT_HTTPHEADER, array(
            "X-Parse-Application-Id: replacewithyourkey",
            "X-Parse-REST-API-Key: replacewithyourkey",
            ));

Now the function will look like this.

public function exec()
    {
        if (!isset($this->curl)) {
            throw new ParseException('You must call ParseCurl::init first');
        }
      curl_setopt($this->curl, CURLOPT_HTTPHEADER, array(
            "X-Parse-Application-Id: replacewithyourkey",
            "X-Parse-REST-API-Key: replacewithyourkey",
            ));
        return curl_exec($this->curl);
   }
dplewis commented 5 years ago

@parasthekoder Does query and saving objects work instead of the health endpoint?

git-elliot commented 5 years ago

Nope, saving objects doesn't work, and queries too. Everything fails with exception unauthorized because these headers aren't included in curl i.e., X-Parse-Application-Id, X-Parse-REST-API-Key (if provided in initialization ) and X-Parse-Master-Key. I've also faced "Invalid field name" error because 'Content-Type: application/json' was also not added in the headers.

dplewis commented 5 years ago

Sorry I am unable to replicate the issue. Can you debug this?

I find it weird that ParseClient::getServerHealth(); didn't work for you. /health endpoint is public and doesn't require keys / headers to ping.

git-elliot commented 5 years ago

After having so many issues with back4app and php. I've installed parse-server locally and found that these headers are included in the latest version and fixed my problem. This issue is related with the back4app api. Where as changing the parse server version doesn't work actually there. I think this button is broken.

back4app

Conclusion : I don't know what time it takes for back4app to change parse version. But I've learnt that don't post issue when using third party APIs.

dplewis commented 5 years ago

It never hurts to post issues. You never know what you might find 👍

paivaric commented 5 years ago

@MrMegamind Back4App needs at least a custom subdomain (your-app.back4app.io) or appId key to send requests to your app. Any request without one of those methods will return unauthorized. The method getServerHealth on PHP SDK doesn't send the appId and you aren't using a subdomain, so it's returning unauthorized. All other methods and functions send at least the appId. So, try to create a subdomain on Server Settings -> Web Hosting + Live Query and use it as your endpoint on setServerURL. After that, try to use getServerHealth.

MrMegamind commented 5 years ago

@paivaric Thank you for suggestion, I gave up a long ago but this might help others facing similar issues. I was only able to solve all the requests by adding custom headers. @parasthekoder thanks for clarifying how to use the workaround. Happy coding