cr1zz
cr1zz

Reputation: 577

Google API + PHP + Ajax Call - Access-Control-Allow-Origin' header is present on the requested resource

I'm using the google API to access my calendar entries via OAuth. Unfortunately I'm getting the following error (server is a local raspi):

Failed to load https://accounts.google.com/o/oauth2/auth?response_type=code&access_type=online&client_id=****-****.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Fopenhabianpi..%2Fsmarthome%2Fphp%2Fscripts%2Fscript.oauth2callback.php&state&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly&approval_prompt=auto: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://openhabianpi..' is therefore not allowed access. The response had HTTP status code 405.

My scripts:

Ajax Request

var termine = function (){
     $.ajax({
        type: "POST",
        url: "php/ajax/ajax.termine.php",
        data: {
            action: 'get_termine'
        },n
        success: function(response) {
            console.log(response);
        }
    });
}

ajax.termine.php

require dirname(dirname(__FILE__)).'/vendor/autoload.php';

$client = new Google_Client();
$client->setAuthConfig(dirname(dirname(__FILE__)).'/config/client_secret.json');
$client->addScope(Google_Service_Calendar::CALENDAR_READONLY);
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $calendarId = 'primary';
  $optParams = array(
    'maxResults' => 10,
    'orderBy' => 'startTime',
    'singleEvents' => TRUE,
    'timeMin' => date('c'),
  );

  $service = new Google_Service_Calendar($client);
  $results = $service->events->listEvents($calendarId, $optParams);
  if (count($results->getItems()) == 0) {
    print "No upcoming events found.\n";
  } else {
    print "Upcoming events:\n";
    foreach ($results->getItems() as $event) {
      $start = $event->start->dateTime;
      if (empty($start)) {
        $start = $event->start->date;
      }
      printf("%s (%s)\n", $event->getSummary(), $start);
        echo date('c');
    }
  }
} else {
  $redirect_uri = 'http://openhabianpi.***.***/smarthome/php/scripts/script.oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

script.oauth2callback

<?php
require_once dirname(dirname(__FILE__)).'/vendor/autoload.php';
session_start();

$client = new Google_Client();
$client->setAuthConfigFile(dirname(dirname(__FILE__)).'/config/client_secret.json');
$client->setRedirectUri('http://openhabianpi.***.***/smarthome/php/scripts/script.oauth2callback.php');
$client->addScope(Google_Service_Calendar::CALENDAR_READONLY);
if (! isset($_GET['code'])) {
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();
  $redirect_uri = 'http://openhabianpi.***.***/smarthome/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

I've tried the following, unfortunately without success:

  1. dataType: 'jsonp',

  2. header("Access-Control-Allow-Origin: *");

  3. Setting in .htaccess or apache.conf

Access-Control-Allow-Origin "*"

Thanks in advance for your help!

Upvotes: 6

Views: 958

Answers (4)

cr1zz
cr1zz

Reputation: 577

The following script is working via ajax (you have to use a service account for this):

    <?php
    /**
    * Session aufbauen und user check
    */
    session_start();

    require dirname(dirname(__FILE__)).'/vendor/autoload.php'; //Google API via Composer

    $json_path = '***PATH to service account credential JSON***';

    $client = new Google_Client();

    $client->setAuthConfig($json_path);
    $client->useApplicationDefaultCredentials();
    $client->addScope(Google_Service_Calendar::CALENDAR_READONLY);

    $client->setApplicationName("***Your Appname***");

    $service = new Google_Service_Calendar($client);

    $calendarId = '***Your CAL ID***';
    $optParams = array(
       'maxResults' => 10,
        'orderBy' => 'startTime',
        'singleEvents' => TRUE,
        'timeMin' => date('c'),
    );

  $results = $service->events->listEvents($calendarId, $optParams);
  if (count($results->getItems()) == 0) {
    print "";
  } else {
    foreach ($results->getItems() as $event) {
      $start = $event->start->dateTime;
      if (empty($start)) {
        $start = $event->start->date;
      }

      $date = date("d.m.Y", strtotime($start));
      $time = date("G:i", strtotime($start));

      $today = date("d.m.Y");

      if ($date == $today){
        $array[] = array(
          "datum" => $date,
          "time" => $time,
          "termin" => $event->summary
        );
      }
    }
  }

  echo json_encode($array);

Upvotes: 0

Pradeep Kumar Kushwaha
Pradeep Kumar Kushwaha

Reputation: 2239

You simply need to visit your google developer account and under API credentials add your web server address or IP address.

Visit console.developers.google.com

Then select your project. Then select credentials. Then select your API key. Then select Application restrictions then select HTTP referrers address and add your address.

enter image description here

Hope it solves your issue.

Upvotes: 0

Viral Jadav
Viral Jadav

Reputation: 66

    if (isset($_SERVER['HTTP_ORIGIN'])){
        header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Max-Age: 86400');    // cache for 1 day
    }
    // Access-Control headers are received during OPTIONS requests
    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') 
    {
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
            header("Access-Control-Allow-Methods: GET, POST,OPTIONS");         
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
            header("Access-Control-Allow-Headers:        {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
        exit(0);
    }

Upvotes: 4

Korri
Korri

Reputation: 657

You can't use AJAX do do an OAuth authentication as the URL returned by $client->createAuthUrl() will show a login page.

You can still stay on the same page by following this steps:

  • Open ajax.termine.php in a new tab.

window.open('php/ajax/ajax.termine.php', '_blank');

  • Set the redirect uri to a blank page that only contains Javascript.
  • Use this javascript to change the parent page URL.

window.top.location.href = 'http://openhabianpi.***.***/smarthome/';

Upvotes: 0

Related Questions