2

Okay... I have to say I don't have enough experience on using Google's API, so I'll try to explain as detail as I could.

I need to use PHP to grab the Cloud storage's data, so I tried my credential with gsUtil to grab data from bucket and it works; But when I try to use PHP library to grab data, the API replied me with this content:

"error": {
  "errors": [
    {
       "domain": "global",
       "reason": "forbidden",
       "message": "Forbidden"
    }
  ],
  "code": 403,
  "message": "Forbidden"
}

Since it didn't tell me exactly which step is wrong, so I searched around this site and tried everything which looked similar, but the Situation stands.

Here is the Configuration on my Google Dev. Console:

Api Manager > Overall > Enabled API:

(a)Drive API.

(b)Cloud Storage.

(c)Cloud Storage JSON API.

Api Manager > Credentials:

(a)Api Key / OAuth 2.0 ID / Service Acc. Key are created.

(b)Server IPs are added to the Api key's accept IP list.

(c)Service Account have the Editor permission to the Project, service acc key is bind to this account too.

In PHP:

$email = '<my gmail>';
$scope = 'https://www.googleapis.com/auth/cloud-platform';
$apiKey = '<my api key>';
$oAuthId = '<OAuth ID>';
$serviceAcc = '<service account id>@developer.gserviceaccount.com';
$keyFileLocation = $_SERVER['DOCUMENT_ROOT']. "/<p12 file>";
$bucketId = '<my bucket id>';
$list = array();

$client = new Google_Client();
$client->setApplicationName("gp-api");
$client->setDeveloperKey($apiKey);
$cred = new Google_Auth_AssertionCredentials (
            $serviceAcc,
            array($scope),
            file_get_contents($keyFileLocation)
    );

$client->setAssertionCredentials($cred);

if($client->getAuth()->isAccessTokenExpired())
  $client->getAuth()->refreshTokenWithAssertion($cred);

if($client->getAccessToken()) {
  $reqUrl = "https://www.googleapis.com/storage/v1/b/$bucketId/o/";
  $request = new Google_Http_Request($reqUrl, 'GET', null, null);
  $httpRequest = $client->getAuth()->authenticatedRequest($request);
  if ($httpRequest->getResponseHttpCode() == 200) {
    $objects = json_decode($httpRequest->getResponseBody());
    foreach ($objects->items as $object) {
      $list[] = $object->mediaLink;
    }
  }
  else {
    echo $httpRequest->getResponseHttpCode(); // This is where I got the 403
  }
}

Please tell me if I missed something.

Kaninchen
  • 455
  • 2
  • 7
  • 19
  • Is it possible you do not have READ permission on the bucket? Alternately, I see you define both $email and $serviceAcc, but you use an undefined variable, $accountName, when creating the Google_Auth_AssertionCredentials. Are you filling that in with some other piece of code? – Brandon Yarbrough Mar 22 '16 at 07:17
  • @Brandon Yarbrough oops, you got my typing error. xD It's fixed now. – Kaninchen Mar 22 '16 at 08:27
  • @Brandon Yarbrough but If I don't have the READ permission, I should have got the Error while I was using gsUtil to read my bucket. But my gsUtils with those credentials works good without problem. – Kaninchen Mar 22 '16 at 08:29
  • Is gsutil using your credentials, or the credentials of service account $serviceAcc? – Brandon Yarbrough Mar 22 '16 at 18:14
  • gsutil use the oAuth2 token(an url will be generated for browse and get the Auth code from it) and project id(which could be found at Dev Console's dashboard, right under the Application/Project name) – Kaninchen Mar 23 '16 at 02:58
  • so technically it did not using that $serviceAcc I think. – Kaninchen Mar 23 '16 at 06:11

1 Answers1

0

Ok, I got the Problem: it must impersonate the User account which have the privilege to access the API scope that I mentioned in program.

So some additional codes must be added as following:

$email = '<email account which could access that api>';
$scope = 'https://www.googleapis.com/auth/cloud-platform';
$apiKey = '<my api key>';
$oAuthId = '<OAuth ID>';
$serviceAcc = '<service account id>@developer.gserviceaccount.com';
$keyFileLocation = $_SERVER['DOCUMENT_ROOT']. "/<p12 file>";
$bucketId = '<my bucket id>';
$list = array();

$client = new Google_Client();
$client->setApplicationName("gp-api");
$client->setDeveloperKey($apiKey);
$cred = new Google_Auth_AssertionCredentials (
        $serviceAcc,
        array($scope),
        file_get_contents($keyFileLocation),
        'notasecret',
        'http://oauth.net/grant_type/jwt/1.0/bearer',
        $email
);

Woooooyaaaaa, another problem solved! time to move up for next problem.

Kaninchen
  • 455
  • 2
  • 7
  • 19