【问题标题】:Unable to create events for different user in Google calendar无法在 Google 日历中为不同用户创建活动
【发布时间】:2021-09-03 18:24:04
【问题描述】:

大家好。 我希望你们都做得很好。

我知道这个问题已经被问过很多次了,但是那里提供的解决方案都不适合我。

我正在自定义 PHP 中实现谷歌日历 API。我遵循了谷歌提供的官方文档。我已经能够为特定用户创建和获取事件。

我最初的目标是让每个用户都可以在自己的日历上获取、创建、更新和删除事件。

这是我在代码中所做的。

这是 calendarSetting.php 文件。

<?php
require __DIR__ . '/vendor/autoload.php';

function getClient()
{
    $client = new Google_Client();
    $client->setApplicationName('Google Calendar API PHP Quickstart');
    $client->setScopes(Google_Service_Calendar::CALENDAR);
    $client->setAuthConfig('client_secret.json');
    $client->setAccessType('offline');
    $client->setPrompt('select_account consent');

    
    $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();
            printf("Open the following link in your browser:\n%s\n", $authUrl);
            print 'Enter verification code: ';
            $authCode = trim(fgets(STDIN));

            // Exchange authorization code for an access token.
            $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
            $client->setAccessToken($accessToken);

            // Check to see if there was an error.
            if (array_key_exists('error', $accessToken)) {
                throw new Exception(join(', ', $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()));
    }
    return $client;
}
?>

这是 createCalendar.php 文件

<?php

  require __DIR__ . '/vendor/autoload.php';
  include('calendarSetting.php');
  session_start();
  $appointment_id = $_SESSION['appointment_id'];
  $patient_fname = $_SESSION['patient_fname'];
  $patient_lname = $_SESSION['patient_lname'];
  $patient_phone = $_SESSION['patient_phone'];
  $schedule = $_SESSION['appointment_date'];
  $start_date = $_SESSION['start'];
  $end_date = $_SESSION['end'];
 
    $client = getClient();
    $service = new Google_Service_Calendar($client);
    $event = new Google_Service_Calendar_Event(array(
        'summary' => $patient_fname . ' ' . $patient_lname,
        'description' => $patient_fname . ' ' . ' ' . $patient_lname . ' ' . $patient_phone ,
        
        'start' => array(
          'dateTime' => $start_date.':00+05:00',
          'timeZone' => 'America/Los_Angeles',
        ),
        'end' => array(
          'dateTime' => $end_date.':00+05:00',
          'timeZone' => 'America/Los_Angeles',
        ),
        'recurrence' => array(
          'RRULE:FREQ=DAILY;COUNT=1'
        ),
        'attendees' => array(
          array('email' => 'abc1211@gmail.com')
        )
         
        
      ));
    
      $calendarId = 'user876@gmail.com';
      $event = $service->events->insert($calendarId, $event);
    printf('Event created');
    header('location: Doctor');


?>

这非常适合 $calendarId = 'user876@gmail.com'; 的用户。但是如果我更改用户,它会给我一个错误。

致命错误:未捕获的 Google\Service\Exception: { "error": { "errors": [ {“域”:“全局”,“原因”:“未找到”,“消息”:“未找到”} ],“代码”:404,“消息”:“未找到”} } 在 F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Http\REST.php:128 堆栈跟踪:#0 F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Http\REST.php(103): 谷歌\Http\REST::decodeHttpResponse(对象(GuzzleHttp\Psr7\Response), 对象(GuzzleHttp\Psr7\Request),'Google_Service_...')#1 [内部 功能]: Google\Http\REST::doExecute(Object(GuzzleHttp\Client), 对象(GuzzleHttp\Psr7\Request),'Google_Service_...')#2 F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Task\Runner.php(182): call_user_func_array(Array, Array) #3 F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Http\REST.php(66): Google\Task\Runner->run() #4 F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Client.php(898): Google\Http\REST::execute(Object(GuzzleHttp\Client), 对象(GuzzleHttp\Psr7\Request),'Google_Service_...',数组,NULL)#5 F:\x 在 F:\xampp\htdocs\bupa1\vendor\google\apiclient\src\Http\REST.php 上 第 128 行

我一直在试图弄清楚为什么会发生这种情况。到目前为止,我发现每次我向谷歌发送请求以创建事件时,我在 calendarSetting.php 文件中的访问令牌都不会刷新。

现在我陷入了如何获取刷新令牌以便新用户也可以创建事件的问题。

如果有人能帮助解决这个问题,我将非常感激。

谢谢

【问题讨论】:

  • 是什么让你认为它是刷新令牌?尝试在 abc1211@gmail.com 上执行 calendar.get,在我看来,您无法访问该日历。你究竟是如何改变用户的?
  • 即将举行的活动:活动 ID:oqter2kiptconjh5nlkm0auldc_20210622T200300Z 活动日期 = 2021-06-20 活动标题 = Potage D- Ace 开始日期 = 2021-06-23T01:03:00+05:00 结束日期 = 2021 -06-23T01:04:00+05:00 事件 ID:c1vqmlbceb4q82eir3da15niko_20210624T065500Z 事件日期 = 2021-06-20 事件标题 = 患者加密测试开始日期 = 2021-06-24T11:55:00+05:00 结束日期 = 2021-06-24T11:56:00+05:00
  • 其实abc1211@gmail.com是与会者的邮箱。目前,创建事件的用户是 user876@gmail.com 我已经分享了我通过 user876@gmail.com 创建的事件列表。
  • 我认为它是刷新令牌的原因是我已经回显了令牌和刷新令牌,它的值对于我想从中创建事件的每个用户都是相同的。
  • 因此,每当我更改用户时,我都会从根目录中删除 token.json 文件,然后发送请求以在 Google 日历上创建事件。首先,它将我重定向到 google 身份验证,并在成功的身份验证之后再次在根目录中创建 token.json 文件。我创建活动的请求也成功了。

标签: php api calendar google-calendar-api refresh-token


【解决方案1】:

您现在拥有的最终将成为一个单用户系统。如果该文件存在,那么其他人将不需要登录。如果您开始删除该文件,那么如果用户 1 仍在使用系统,那么他们将使用文件中的用户 2 令牌读取数据。

如果这是一个网络应用程序,您应该使用会话变量。

oauth2callback.php

require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/Oauth2Authentication.php';

// Start a session to persist credentials.
session_start();

// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
    $client = buildClient();
    $auth_url = $client->createAuthUrl();
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
    $client = buildClient();
    $client->authenticate($_GET['code']); // Exchange the authencation code for a refresh token and access token.
    // Add access token and refresh token to seession.
    $_SESSION['access_token'] = $client->getAccessToken();
    $_SESSION['refresh_token'] = $client->getRefreshToken();    
    //Redirect back to main script
    $redirect_uri = str_replace("oauth2callback.php",$_SESSION['mainScript'],$client->getRedirectUri());    
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Oauth2Authentication.php

您应该检查此文件中所有代码的完整链接。请注意它如何将用户令牌存储在会话变量中,因此每个用户都有自己的令牌存储在其浏览器中。

function getOauth2Client() {
    try {
        
        $client = buildClient();
        
        // Set the refresh token on the client. 
        if (isset($_SESSION['refresh_token']) && $_SESSION['refresh_token']) {
            $client->refreshToken($_SESSION['refresh_token']);
        }
        
        // If the user has already authorized this app then get an access token
        // else redirect to ask the user to authorize access to Google Analytics.
        if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
            
            // Set the access token on the client.
            $client->setAccessToken($_SESSION['access_token']);                 
            
            // Refresh the access token if it's expired.
            if ($client->isAccessTokenExpired()) {              
                $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
                $client->setAccessToken($client->getAccessToken()); 
                $_SESSION['access_token'] = $client->getAccessToken();              
            }           
            return $client; 
        } else {
            // We do not have access request access.
            header('Location: ' . filter_var( $client->getRedirectUri(), FILTER_SANITIZE_URL));
        }
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}

【讨论】:

  • 是的,您完全正确,如果我删除该文件会给其他用户带来麻烦。在这种情况下,使用会话变量似乎确实有效。我需要试试这个。非常感谢您的宝贵时间。
  • 如果有帮助,记得接受 anwser。如果您有任何问题,请使用您的新代码提出一个新问题,我应该会发现它。
  • 是的,当然。
  • 所以我使用了会话变量。每次用户从谷歌获得身份验证时,我都会从 url 获取代码。但是当它重定向到 oauth2callback.php 时,它开始出现另一个错误。
  • $client->authenticate($_GET['code']); $token = $client->getAccessToken();
猜你喜欢
  • 2021-10-31
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 2023-03-07
  • 1970-01-01
相关资源
最近更新 更多