Выполнение межсерверного запроса к API Календаря Google

Я создаю SPA, используя vue.js, который имеет внутренний сервер PHP (slim framework 3). Это два отдельных проекта, оставляют на двух разных серверах и у бэкенда вообще нет фронтенда.

SPA (vue.js) делает запросы к бэкенду через ajax.

Теперь я хочу реализовать Google Calendar API для создания календаря и событий каждый раз, когда пользователь создает элемент списка дел. Для этого мне нужен межсерверный доступ к Google Calendar API (мне может потребоваться внести изменения в событие в GCAL, даже если пользователь не вошел в систему).

Что я пытаюсь понять, как я могу получить токен доступа (и токен обновления) с помощью библиотеки Google JS с помощью vue.js и сохранить его в базе данных, чтобы мой бэкэнд мог использовать его для отправки автономных запросов к GCAL Api.

Когда я использую Oauth v.2 с библиотекой JS, все, что я получаю, — это access_token, который нельзя использовать для связи между серверами.

[ОБНОВЛЕНИЕ]

Хорошо, еще немного информации. Я следую инструкциям Google, и мой интерфейс выглядит следующим образом: момент jsbin

Таким образом, я могу успешно авторизовать пользователя и получить доступ к его календарю с помощью javascript sdk. Но токен, который возвращает Javascript SDK, выглядит примерно так:

{
_aa: "1"
access_token: "xxxxxxx"
client_id: "yyyyyyyyyy"
cookie_policy: undefined
expires_at: "1456400189"
expires_in: "3600"
g_user_cookie_policy: undefined
issued_at: "1456396589"
response_type: "token"
scope: "https://www.googleapis.com/auth/calendar"
state: ""
status: Object
google_logged_in: false
method: "AUTO"
signed_in: true
token_type: "Bearer"
}

Я отправляю этот токен на свой внутренний сервер и пытаюсь сделать запрос к API GCAL следующим образом.

$token = $request->getParam('token');
    $client = new Google_Client();
    $client->setApplicationName('Web');
    $client->setScopes([Google_Service_Calendar::CALENDAR]);
    $client->setAuthConfigFile(ROOT_DIR . '/client_secret.json');
    $client->setAccessType('offline');
    $client->setAccessToken(json_encode($token));
    $service = new Google_Service_Calendar($client);

    $calendarId = 'primary';
    $optParams = array(
        'maxResults' => 10,
        'orderBy' => 'startTime',
        'singleEvents' => TRUE,
        'timeMin' => date('c'),
    );
    $results = $service->events->listEvents($calendarId, $optParams);

И он возвращает ошибку о том, что срок действия токена истек. Я проверил код Google и обнаружил, что причина, по которой он возвращает эту ошибку, связана с этими строками.

    public function isAccessTokenExpired()
  {
    if (!$this->token || !isset($this->token['created'])) {
      return true;
    }

    // If the token is set to expire in the next 30 seconds.
    $expired = ($this->token['created']
        + ($this->token['expires_in'] - 30)) < time();

    return $expired;
  }

Как вы можете видеть, токен, который поступает из внешнего интерфейса, не имеет поля created, а также поля refresh_token.


person Optimus    schedule 24.02.2016    source источник
comment
хотел бы помочь, но ваш вопрос очень широк. Пожалуйста, опубликуйте код, который вы написали, результат, который вы получаете, и результат, который вы хотите получить. Тогда мы сможем понять, что происходит не так.   -  person Jeff    schedule 25.02.2016


Ответы (1)


Спасибо за обновление вопроса! Я думаю, проблема в том, что использование потока на стороне клиента не позволяет вам получить токен обновления. Из документов:

Поток на стороне клиента OAuth 2.0 (также известный как неявный поток) используется для получения токенов доступа (он не поддерживает выдачу токенов обновления) и оптимизирован для общедоступных клиентов, которые, как известно, работают с определенным URI перенаправления. Эти клиенты обычно реализуются в браузере с использованием языка сценариев, такого как JavaScript.

Сервер авторизации НЕ ДОЛЖЕН выдавать токен обновления.

подробнее см.: Как получить токен обновления во время с помощью JS-клиента Google API

Вам нужно будет использовать поток аутентификации сервера, чтобы получить токен, который вы можете обновить и использовать в течение длительного времени. Вот краткое руководство по PHP.

Еще одна вещь, которую следует учитывать, это то, что вы получите refresh_token только первый раз, когда кто-то авторизует ваше приложение. После этого попытки аутентификации будут возвращать только токен доступа. Поэтому, если вы потеряете токен обновления, вам нужно будет либо отключить авторизацию из своей учетной записи Google, либо использовать опцию «принудительной повторной аутентификации» в API.

person Jeff    schedule 25.02.2016
comment
Спасибо за ответ. Вот этого я и боялся :) Так что мне нужно перенаправить пользователя на backend сервер (PHP) и там на авторизацию и сохранить токен в бд и перенаправить обратно в SPA. - person Optimus; 25.02.2016