首页 文章

谷歌日历刷新令牌和编码器

提问于
浏览
0

我正在使用Google Calendar API在fullcalendar上显示事件(因此在我的视图中使用json对象) . 我正在使用codeignitor 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');
}

function 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'];
            }

我刚刚注意到它在我的授权中曾经说过“授予离线访问权限”,但现在它不再提及谷歌文档说“用户授予对请求范围的离线访问权限后,您可以继续使用API客户端访问当用户离线时,代表用户使用Google API . 客户端对象将根据需要刷新访问令牌 . “

enter image description here

1 回答

  • 0

    在您第一次获得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问题 .

相关问题