php - 使用日历api使用google-api-php-client进行谷歌服务帐户身份验证

标签 php google-calendar-api codeigniter-2 google-api-php-client

我正在使用 php 5.3.3 和 codeigniter 2.1.0。 我想做的是设置一个服务帐户,这样用户就可以在我网站的文本输入字段中添加约会,然后将该约会添加到共享的 Google 日历中。

我有一个谷歌帐户,并使用:https://code.google.com/apis/console我创建了一个名为“pqp”的新项目 在服务上:启用了日历 API 在 api 访问上:我创建了一个 oath 2.0 客户端 ID……产品名称 = pqp,应用程序类型 = 服务帐户。

下载了 key 46…-privatekey.p12。有设置的截图:

preview

我得到了 google-api-php-client 的 svn checkout (28/6/2012) 在 google-api-php-client/src/config.php 中,我更改了行:

25: 'application_name' => 'pqp',
28: 'oauth2_client_id' => '373xxx730.apps.googleusercontent.com',
57: 'ioFileCache_directory'  => 'tmp/apiClient',  // my apache user does not have access to the system /tmp folder.  + tmp/apiClient has permissions of 777 on the server.

使用此链接:

http://code.google.com/p/google-api-php-client/source/browse/trunk/examples/prediction/serviceAccount.php?spec=svn445&r=395

我修改为:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Test extends CI_Controller{
    function __construct()
    {
        parent::__construct();
    }
    function index()
    {
        set_include_path(get_include_path() . PATH_SEPARATOR .dirname(__FILE__).'/../libraries/google-api-php-client/src');
        ini_set('error_reporting',E_ALL);
        ini_set('display_errors','1');
        // Set your client id, service account name, and the path to your private key.
        // For more information about obtaining these keys, visit:
        // https://developers.google.com/console/help/#service_accounts
        define('CLIENT_ID','3731xxx44730.apps.googleusercontent.com');
        define('SERVICE_ACCOUNT_NAME','373xxx244730@developer.gserviceaccount.com');
        // Make sure you keep your key.p12 file in a secure location, and isn't
        // readable by others.
        define('KEY_FILE',dirname(__FILE__).'/../../461290xxx796c0b7db9582c-privatekey.p12');

        require_once "apiClient.php";
        require_once "contrib/apiCalendarService.php";

        $client = new apiClient();
        $client->setApplicationName("pqp");     
        // Set your cached access token. Remember to replace $_SESSION with a
        // real database or memcached.
        session_start();
        if (isset($_SESSION['token'])) {
            $client->setAccessToken($_SESSION['token']);
            echo 'client access token is set.<br/>';
        }

        // Load the key in PKCS 12 format (you need to download this from the
        // Google API Console when the service account was created.
        $key = file_get_contents(KEY_FILE);
        $creds = new apiAssertionCredentials(SERVICE_ACCOUNT_NAME,array('https://www.googleapis.com/auth/calendar'),$key);
        $client->setAssertionCredentials($creds);
        $client->setClientId(CLIENT_ID);
        $service = new apiCalendarService($client);
        echo 'client:<br/>';
        var_dump($client);
        echo 'service:<br/>';
        var_dump($service);
        // We're not done yet. Remember to update the cached access token.
        // Remember to replace $_SESSION with a real database or memcached.
        if ($client->getAccessToken()) {
            $_SESSION['token'] = $client->getAccessToken();
            echo 'token is good!, so creating an event....';
            echo $this->insert_event($service,'testing summary','my location','2012-06-29T10:00:00.000+10:00','2012-06-29T10:00:00.000+10:00');
        }
    }


    function insert_event($service,$summary,$location,$from,$to){
        $event = new Event();
        $event->setSummary($summary);
        $event->setLocation($location);
        $start = new EventDateTime();
        $start->setDateTime($from);
        $event->setStart($start);
        $end = new EventDateTime();
        $end->setDateTime($to);
        $event->setEnd($end);
        $attendee1 = new EventAttendee();
        $attendee1->setEmail('test@example.com');
        $attendees = array($attendee1);
        $event->attendees = $attendees;
        $createdEvent = $service->events->insert('primary', $event);
        return $createdEvent->getId();

    }
}

输出的馅饼是here :

$client 对象未认证,未设置 getAccessToken,未插入事件。

我发现很难确定要更改 $config 文件中的哪些设置,因为有不同的命名法。我想这是代码进展的产物。 src/config.php 中的设置是否正确?我需要更改更多设置吗?

据我了解,如果我创建服务帐户,下载 key 文件,并使用我的开发者 ID 下载此文件的内容,它应该会返回一个 token ,并且无需设置重定向 uri..那是对的吗?这是我想要的功能。我不希望用户必须授权访问,因为该网站只会与一个谷歌帐户交互。

所以,问题是,我如何让这个日历 API 使用谷歌服务帐户进行身份验证?

最佳答案

你可以试试this一个如果你还没有...

编辑: this一个有趣的,但如果你仍然想自己写一个,那就试试 this oauth2 的母亲。 helpful

关于您使用的 google-api-php-client 上的服务帐户(始终使用带有 SVN 的主干帐户)我在该代码操作中找不到任何引用 apiAssertionCredentials::generateAssertion() 那里肯定没有对 auth 的调用

public function __construct(
      $serviceAccountName,
      $scopes,
      $privateKey,
      $privateKeyPassword = 'notasecret',
      $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
      $prn = false) {
    $this->serviceAccountName = $serviceAccountName;
    $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
    $this->privateKey = $privateKey;
    $this->privateKeyPassword = $privateKeyPassword;
    $this->assertionType = $assertionType;
    $this->prn = $prn;
}

我猜应该调用这个方法...

public function generateAssertion() {
    $now = time();

    $jwtParams = array(
          'aud' => apiOAuth2::OAUTH2_TOKEN_URI,
          'scope' => $this->scopes,
          'iat' => $now,
          'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
          'iss' => $this->serviceAccountName,
    );

    if ($this->prn !== false) {
      $jwtParams['prn'] = $this->prn;
    }

    return $this->makeSignedJwt($jwtParams);
}

编辑: 赦免。在新鲜的版本。看起来像是 Google_OAuth2::refreshTokenWithAssertion() 实际上谁应该开始真正的过程

关于php - 使用日历api使用google-api-php-client进行谷歌服务帐户身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11256933/

相关文章:

php - 数组不向前传送数据

php - 使用 COALESCE 返回带有导航数组页面信息的 META 标题值

php - UTF-8贯穿始终

ruby-on-rails - 与 Rails 3 站点的完整谷歌日历集成

c++ - "Remember the milk"订阅日历的 Google 日历同步问题

javascript - 函数 createEvent 返回 null

php - 表单验证 - 修改 codeigniter 中的第二个参数

php - 基于 Codeigniter 数据库的配置设置

php - 使用 PhpBrowser 的 Codeception 似乎不遵循重定向

php - SQL 将 ORDER BY 结果作为数组返回