Клиент Google API: проблема с токеном отозвана

Я использую гем google-api-client в своем проекте Rails. У меня работают omniauth и devise, а пользователи аутентифицируются через Google.

Я думал, что у меня все идет очень хорошо, до недавнего времени. Я заметил, что мое приложение выдает ошибку, когда оно получает API Календаря Google через час. Срок действия составляет один час с момента аутентификации, и с этого момента я получаю эту ошибку:

Signet::AuthorizationError (Authorization failed.  Server message:
{
   "error" : "invalid_grant",
   "error_description" : "Token has been revoked."
}):

Это отдельно от недопустимых токенов обновления, поскольку у меня есть токен обновления, хранящийся в базе данных. Он отправляет запрос токена обновления, который вызывает эту ошибку выше, с этим кодом:

client = Google::APIClient.new(
  :application_name => APP_NAME,
  :application_version => APP_VERSION,
)

client.authorization.client_id = CLIENT_ID
client.authorization.client_secret = CLIENT_SECRET

client.authorization.refresh_token = user.auth_refresh_token
token_result = client.authorization.fetch_access_token!

Я был очень осторожен, чтобы не входить и не выходить из своих учетных записей Google, поэтому я не могу понять, почему Google отправил обратно это сообщение. Если я обновлю страницу через 55 минут, все в порядке. Если я обновляю страницу через 1 час, она жалуется на отзыв токена доступа.

У кого-нибудь была эта проблема раньше? Если да, то что вы сделали, чтобы исправить это? Вам нужно было что-то изменить в консоли разработчика Google?


person JakeLarson    schedule 09.09.2015    source источник
comment
Вы когда-нибудь решали это? Вроде такая же проблема.   -  person meder omuraliev    schedule 12.01.2016
comment
@mederomuraliev Я добавил ответ из того, что смог вспомнить, когда исправил это. Надеюсь, это полезно.   -  person JakeLarson    schedule 13.01.2016


Ответы (1)


Я закончил тем, что выяснил проблему, поэтому решил поделиться тем, что ее исправило.

В config/initializers/devise.rb у меня есть:

scope: 'userinfo.profile, userinfo.email, calendar, https://www.googleapis.com/auth/gmail.readonly', prompt: 'select_account consent' }

Что мне помогло, так это часть prompt: 'select_account consent'. Запрос согласия пользователя при каждом входе в систему, по-видимому, поддерживает актуальность токена обновления. Когда пользователь входит в систему через Google, я проверяю, есть ли в ответе токен обновления, и если он есть, я сохраняю его в базе данных. Если нет, я сохраняю их текущий токен обновления в базе данных.

Честно говоря, я действительно не понимаю, почему мне это было необходимо, но для других пользователей, которые поделились своими примерами кода, это было нормально. Возможно, было изменение в OAuth2 Google или, может быть, есть несоответствие в моем методе обработки авторизации.

person JakeLarson    schedule 13.01.2016
comment
Потрясающий. Спасибо за ваш ответ. Я смог решить свою проблему, и мне в основном пришлось регенерировать токен, потому что пароль был изменен, и он был отозван. Просто на случай, если кто-нибудь еще столкнется с этим. - person meder omuraliev; 14.01.2016