dongshixingga7900 2012-06-29 06:15
浏览 83

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

i am using php 5.3.3, and codeigniter 2.1.0. what i want to do is set up a service account, so a user can add an appointment in a text entry field on my website, then have that appointment added to a shared shared google calendar.

i have a google account, and using : https://code.google.com/apis/console I created a new project called 'pqp' on services: enabled the calendar api on api access: i created an oath 2.0 client id… product name = pqp, application type = service account.

downloaded the key 46… -privatekey.p12. there is a screenshot of the settings:

preview

I got an svn checkout of the google-api-php-client (28/6/2012) In the google-api-php-client/src/config.php I changed lines:

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.

using this link:

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

I modified it to:

<?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();

    }
}

a pastie of the output is here:

the $client object is not authenticated, the getAccessToken is not set, and the event is not inserted.

i have found it difficult to work out which settings in the $config file to change because there is different nomenclature. i guess this is an artifact of how the code has progressed. are the settings in src/config.php correct? do i need to alter any more settings?

it is my understanding that if i create the service account, download the key file, and the contents of this file with my developer id, it should return a token, and there is no need to set up a redirection uri.. is that correct? this is the functionality i want. i don't want the user to have to authorise access because the website will only ever interact with one google account.

So, the question is, how do i get this calendar api to authenticate using a google service account?

  • 写回答

1条回答 默认 最新

  • duanhua5523 2012-08-04 22:49
    关注

    You can try this one if you not already...

    EDIT: this one intresting but if you still feel like to write one yourself then try this THE mother of the oauth2. helpful

    About Service Account at google-api-php-client that you use(always take the trunk's one with SVN) I can't found in that code manipulations any reference apiAssertionCredentials::generateAssertion() definitely there is no call to auth in there

    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;
    }
    

    and this method should be called I guess...

    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);
    }
    

    EDIT: Pardon. In fresh ver. look's like it's Google_OAuth2::refreshTokenWithAssertion() actualy who should start the real proces

    评论

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?