google 日历刷新令牌和 codeigniter

google calendar refresh token and codeigniter

我正在使用 Google 日历 API 在完整日历上显示事件(因此在我看来使用 json 对象)。我正在使用 codeigniter php 框架,我在我的控制器中有一些函数来创建一个新的客户端,然后我在 oauth2callback() 函数中使用它来将我的代码交换为 access_token 然后我开始在 gcalendar() 和 gcalendar_events 中调用服务。我已将 accessType 设置为离线,但这似乎并不能使我离线访问事件。它工作得很好,除了每次会话结束时我都被重定向到再次登录。我不想这样,我希望它们在会话结束后一直显示。我正在尝试使用刷新令牌以防 access_token 过期,看看是否可以解决问题。

这是我控制器中的代码

    function getClient() {
        $client = new Google_Client();
        $client->setApplicationName("DL Calendar");
        $client->setAuthConfig('application/client_secrets.json');
        $client->addScope('profile');
        $client->setIncludeGrantedScopes(true);
        $client->setAccessType('offline');

        return $client;
}

  function gcalendar() {
    $this->load->add_package_path(APPPATH . 'vendor/autoload');

    $client = $this->getClient();
    //$client->setRedirectUri(site_url('calendar/index'));
    $client->addScope(Google_Service_Calendar::CALENDAR);

    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {

        $client->setAccessToken($_SESSION['access_token']);
        $access_token = $_SESSION['access_token'];

        $service = new ]Google_Service_Calendar($client);                    
        $calendar = new Google_Service_Calendar_Calendar();
                //$calendarList = $service->calendarList->listCalendarList();
        $calendar = $service->calendars->get('primary');

               $params = array(
                    'owner_id' => get_current_user_id(),
                    'title' => get_current_user(). ' ' .'Google Calendar',
                    'type' => 'gcal',
                    'url' => $calendar->id,   
                );

        $calendar_id = $this->Calendar_model->add_calendar($params); 
        redirect('calendar/index');

    } else {

        $redirect_uri = site_url('calendar/oauth2callback');
        header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
     }
        $this->session->set_flashdata('success', 'Event Successfully Added');
}

函数 oauth2callback() {

    //Build the client object
        $client = $this->getClient();
        $client->addScope(Google_Service_Calendar::CALENDAR); 
        $service = new Google_Service_Calendar($client);

        $url = parse_url($_SERVER['REQUEST_URI']); parse_str($url['query'], $params);
        $code = $params['code'];

    //To exchange an authorization code for an access token, use the authenticate method:
        if (! isset($code)) {
            $auth_url = $client->createAuthUrl();
            header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

        } else {

            $token = $client->fetchAccessTokenWithAuthCode($code);     
            $client->setAccessToken($token);
            $client->authenticate($code);      
            $_SESSION['access_token'] = $client->getAccessToken();
            $redirect_uri = site_url('calendar/gcalendar');
            header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
         }              

}

function gcalendar_events() {
    $client = $this->getClient();

    $client->addScope(Google_Service_Calendar::CALENDAR);
   // $client->setRedirectUri(site_url('calendar/gcalendar'));
    $client->setAccessType('offline'); //need calendar events to appear even if not logged in to google     
    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {

        $client->setAccessToken($_SESSION['access_token']);      
        $access_token = $_SESSION['access_token'];

        $service = new Google_Service_Calendar($client);
        $id = 'primary';   
        $calendar = new Google_Service_Calendar_Calendar();
        $calendar = $service->calendars->get('primary');

        $event = new Google_Service_Calendar_Event();

        $events = $service->events->listEvents($id);

            foreach ($events->getItems() as $event) {          

                $startTime = strtotime($event->getStart()->dateTime)  ;
                $endTime = strtotime($event->getEnd()->dateTime);
                $start = date('Y-m-d H:i:s', $startTime);
                $end = date('Y-m-d H:i:s', $endTime);

                $eventsArr[] = array(
                                'title' => $event->getSummary(),               
                                'start'=> $start,                   
                                'end' =>  $end,
                            ); 
                        }  
                        // Return a single `events` with all the `$eventsArr`
                        echo json_encode($eventsArr);


    }
}

我的会话结束时出现问题吗?或者访问令牌是否过期并且我需要刷新令牌?我应该在哪里设置刷新令牌,因为我尝试将它放在多个地方,但我收到一条错误消息,指出必须将刷新令牌设置为 setAccessToken 的一部分。我把它全部放在一边,但仍然收到错误消息。

这是我使用的代码

     if ($client->isAccessTokenExpired()) {
                            $refresh_token =     $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
                            $client->setAccessToken($refresh_token);
                            $_SESSION['access_token'] = $refresh_token;
                            $this->load->helper('file');
                         write_file('application/client_secrets.json',   json_encode($client->getAccessToken()));
     } else {
        $access_token = $_SESSION['access_token'];
            }

我刚刚注意到它曾经在我的授权中说 'grant offline access' 但现在它不再提到 google 文档说 "After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed."

在您第一次使用 Google 授权期间,您将收到一个令牌,该令牌将在 3600 秒或一小时后过期。因此,您需要使用刷新令牌来获取新的工作令牌。

是这样的SO question

$token = $client->getAccessToken();
$authObj = json_decode($token);
if(isset($authObj->refresh_token)) {
save_refresh_token($authObj->refresh_token);
}

确保保存此 refresh_token。

您可以更新它:

$client->refreshToken($your_saved_refresh_token);

然后将您的新访问令牌设置到会话:

$_SESSION['access_token'] = $client->getAccessToken();

我也建议你访问这个quickstart of Google Calendar for PHP

有关详细信息,请查看此相关的 SO 问题。

  • How to refresh token with Google API client?