ferdinand
ferdinand

Reputation: 409

Error code 401 when create a google slide API on Laravel

I'm studying google slide API on laravel framework now. i want to create a simple template at first but i stuck. i got this error.

{ "error": { "code": 401, "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "errors": [ { "message": "Login Required.", "domain": "global", "reason": "required", "location": "Authorization", "locationType": "header" } ], "status": "UNAUTHENTICATED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "CREDENTIALS_MISSING", "domain": "googleapis.com", "metadata": { "service": "slides.googleapis.com", "method": "google.apps.slides.v1.PresentationsService.CreatePresentation" } } ] } }

I've been following the tutorial to obtain the OAuth credential with file .json on https://console.cloud.google.com and store it to folder "storage > app" folder

{"web":{"client_id":"xxx.apps.googleusercontent.com","project_id":"xxx","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"xxx","redirect_uris":["mydomain"],"javascript_origins":["mydomain"]}}

and here is my code

<?php

namespace App\Http\Controllers;

use Google\Client as GoogleClient;
use Google\Service\Slides;
use Google\Service\Slides\BatchUpdatePresentationRequest;
use Google\Service\Slides\Presentation;
use Google\Service\Slides\CreateSlideRequest;
use Google\Service\Slides\LayoutPlaceholderIdMapping;
use Google\Service\Slides\InsertTextRequest;

class SlideController extends Controller
{
    public function index()
    {
        $credentialsPath = storage_path('app/slide-api-credential.json');

        $client = new GoogleClient();
        $client->setAuthConfig($credentialsPath);
        $client->addScope('Slides::PRESENTATIONS');
        $slides = new Slides($client);
        
        $presentation = new Presentation([
            'title' => 'My First Slide'
        ]);

        $slideRequests = [
            new CreateSlideRequest([
                'slideLayoutReference' => [
                    'predefinedLayout' => 'BLANK'
                ],
                'placeholderIdMappings' => [
                    new LayoutPlaceholderIdMapping([
                        'objectId' => 'TITLE',
                        'layoutPlaceholder' => [
                            'type' => 'TITLE'
                        ]
                    ]),
                    new LayoutPlaceholderIdMapping([
                        'objectId' => 'SUBTITLE',
                        'layoutPlaceholder' => [
                            'type' => 'SUBTITLE'
                        ]
                    ])
                ]
            ]),
            new InsertTextRequest([
                'objectId' => 'TITLE',
                'text' => 'Hello,'
            ]),
            new InsertTextRequest([
                'objectId' => 'SUBTITLE',
                'text' => 'World!'
            ])
        ];

        $batchUpdateRequest = new BatchUpdatePresentationRequest([
            'requests' => $slideRequests
        ]);

        $createdPresentation = $slides->presentations->create($presentation);
        $presentationId = $createdPresentation->presentationId;

        $slides->presentations->batchUpdate($presentationId, $batchUpdateRequest);

        return "Slide created with ID: $presentationId";
    }

}

just create a simple presentation slide. How do i able to solve this? please help

Upvotes: 1

Views: 189

Answers (1)

Bryan Monterrosa
Bryan Monterrosa

Reputation: 1470

To make API calls to the Google Slides API you'll need to provide an authentication method, normally an Access Token, the slide-api-credential.json file is used to link your App to your Google Cloud Project in order to use the enabled APIs.

Your next step would be #2 from their documentation:

Before your application can access private data using a Google API, it must obtain an access token that grants access to that API.

Maybe this could help you get in the right direction, I used this example from their Github repository in order to create a version of your code that would take the user through verification, save the token and use it to call the API:

public function index()
  {
    /********* Generating the Client and OAuthToken ******************/

    $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];

    $client = new GoogleClient();
    $client->setScopes('Slides::PRESENTATIONS');
    $client->setAuthConfig('app/slide-api-credential.json');
    $client->setRedirectUri($redirect_uri);
    $client->setAccessType('offline');
    $client->setPrompt('select_account consent');

    // Load previously authorized token from a file, if it exists.
    // The file token.json stores the user's access and refresh tokens, and is
    // created automatically when the authorization flow completes for the first
    // time.
    $tokenPath = 'token.json';
    if (file_exists($tokenPath)) {
      $accessToken = json_decode(file_get_contents($tokenPath), true);
      $client->setAccessToken($accessToken);
    }

    // If there is no previous token or it's expired.
    if ($client->isAccessTokenExpired()) {
      // Refresh the token if possible, else fetch a new one.
      if ($client->getRefreshToken()) {
        $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
      } else {
        // Request authorization from the user.
        $authUrl = $client->createAuthUrl();
        header('Location:' . $authUrl);
        if (isset($_GET['code'])) {
          $accessToken = $client->fetchAccessTokenWithAuthCode($_GET['code'], $_SESSION['code_verifier']);
          $client->setAccessToken($accessToken);
          // redirect back to the example
          header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
          $client->setAccessToken($accessToken);
        }
      }
      // Save the token to a file.
      if (!file_exists(dirname($tokenPath))) {
        mkdir(dirname($tokenPath), 0700, true);
      }
      file_put_contents($tokenPath, json_encode($client->getAccessToken()));
    }

    /******** End of Authorization Flow *********/

    $slides = new Slides($client);

    $presentation = new Presentation([
      'title' => 'My First Slide'
    ]);
    
    ...

More documentation:

Upvotes: 0

Related Questions