Google :: Apis :: AuthorizationError(未经授权)

Mee*_*eSN 18 ruby-on-rails google-client google-oauth gmail-api

我们正在创建一个以Ionic框架作为前端和Ruby on Rails作为后端的应用程序.我们可以在我们的应用中关联Gmail帐户.帐户链接工作正常,我们从前端获取serverAuthCode,然后使用它获取刷新令牌,我们可以在第一次尝试时使用该刷新令牌获取电子邮件.但在几秒钟内,它就会过期或被撤销.得到以下问题:

Signet::AuthorizationError (Authorization failed.  Server message:
{
  "error" : "invalid_grant",
  "error_description" : "Token has been expired or revoked."
})
Run Code Online (Sandbox Code Playgroud)

看起来,刷新令牌本身就会在几秒钟内到期.有没有人知道如何解决它?

更新:

现有代码如下所示:

class User   
  def authentication(linked_account)
    client = Signet::OAuth2::Client.new(
    authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
    token_credential_uri: Rails.application.secrets.token_credential_uri,
    client_id: Rails.application.secrets.google_client_id,
    client_secret: Rails.application.secrets.google_client_secret,
    scope: 'https://www.googleapis.com/auth/gmail.readonly, https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/userinfo.profile',
    redirect_uri: Rails.application.secrets.redirect_uri,
    refresh_token: linked_account[:refresh_token]
  )

  client.update!(access_token: linked_account.token, expires_at: linked_account.expires_at)
  return  AccessToken.new(linked_account.token) unless client.expired?
  auth.fetch_access_token! 
 end

 def get_email(linked_account)
   auth = authentication(linked_account)
   gmail = Google::Apis::GmailV1::GmailService.new
   gmail.client_options.application_name = User::APPLICATION_NAME
   gmail.authorization = AccessToken.new(linked_account.token)
   query = "(is:inbox OR is:sent)"
   gmail.list_user_messages(linked_account[:uid], q: "#{query}")
   ## Getting error over here ^^
  end
end // class end 

class AccessToken
  attr_reader :token
  def initialize(token)
    @token = token
  end

  def apply!(headers)
    headers['Authorization'] = "Bearer #{@token}"
  end
end
Run Code Online (Sandbox Code Playgroud)

参考链接:https://github.com/google/google-api-ruby-client/issues/296

小智 0

认为refresh token永远不会过期的想法其实是一种误解。实际场景是服务器发出一个短期访问令牌和一个长期刷新令牌。因此,实际上发生的情况是,可以使用长期刷新令牌重新获得访问令牌,但是,您必须请求新的刷新令牌(因为它也会过期!)。例如; 您可以将刷新令牌视为永不过期。但是,在登录检查新令牌时,如果用户撤销刷新令牌,在这种情况下,Google 将在登录时提供新的刷新令牌,因此只需更新刷新令牌即可。

现在的情况可能是用户撤销了对您的应用程序的访问权限。在这种情况下,遗嘱refresh token就会过期(或者我实际上应该说它将成为未经授权的遗嘱)。因此,如果您遇到这种情况,您将必须考虑避免撤销应用程序的访问权限。

为了更好地理解它,您可以参考本文档甚至OAuth 2.0 文档