ruby-on-rails - Google::Apis::AuthorizationError(未授权)

标签 ruby-on-rails google-oauth gmail-api google-client

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

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

看来,刷新 token 本身将在几秒钟内到期。有谁知道如何解决它?

更新:

现有代码如下所示:
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

引用链接:https://github.com/google/google-api-ruby-client/issues/296

最佳答案

据我猜测,问题似乎出在这两行上。检查 token 到期和生成新 token 的方式。如果有最少的可重现代码,那就太好了。

return  AccessToken.new(linked_account.token) unless client.expired?
auth.fetch_access_token! 

以下是我获取访问 token 的方式:
  def self.access_token(refresh_token)
    Cache.fetch(refresh_token, expires_in: 60.minutes) do
      url = GoogleService::TOKEN_CREDENTIAL_URI
      # p.s. TOKEN_CREDENTIAL_URI = 'https://www.googleapis.com/oauth2/v4/token'
      _, response = Request.post(
        url,
        payload: {
          "client_id": GoogleService::CLIENT_ID,
          "client_secret": GoogleService::CLIENT_SECRET,
          "refresh_token": refresh_token,
          "grant_type": "refresh_token"
        }
      )
      response['access_token']
    end
  end

然后将此访问 token 用于任何目的。让我知道它是如何进行的,以及您是否能够创建 API 的可重现版本。那挺棒的。

关于ruby-on-rails - Google::Apis::AuthorizationError(未授权),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50523052/

相关文章:

gmail-api - Gmail api 在调用 message.get 时返回 404 错误

Google Cloud 函数使用服务帐户域范围访问调用 Gmail API

ruby-on-rails - 是否有针对 Rails、Ruby、Erb 的 Xcode 语法着色?如果没有,我怎么能自己写一个?

ruby-on-rails - Rails 3.1.rc4 中的 Omniauth

javascript - 让我的用户使用 Google 登录的首选 JavaScript 方法实际上是什么?

php - redirect_uri : Invalid scheme: <http: 的参数值无效

gmail-api - 带有 nodeJS 的 GMail API - 发送给出 400 错误请求

ruby-on-rails - rails 不同的货币格式

ruby-on-rails - Rails 路由弃用警告

javascript - Rails/JS - 在某些情况下,G+ 登录按钮仅在页面重新加载后有效