ruby on rails-将Google::Auth::Stores::FileTokenStore与数据库一起使用



我正在尝试在我的应用程序中实现对Google API的三腿身份验证,以便能够访问注册用户的Google日历。

在quickstartRuby指南中,这个命令出现了,据我所知,应该指向用户的令牌:

token_store = Google::Auth::Stores::FileTokenStore.new(file: CREDENTIALS_PATH)

它期望令牌存储在一个文件(或Redis)中,但(当然)我将每个用户的令牌存储在我的数据库(Postgres)中。

我是否错误地或以其他方式理解了该命令的目的——如何将其用于数据库存储?

官方文档

我自己根据@Rafe的答案实现了它。只是想分享,以防有人想复制ActiveRecord/Database存储实现:

module Google
  module Auth
    module Stores
      class DatabaseTokenStore < Google::Auth::TokenStore
        def load(id)
          user = User.find(id)
          {
            "client_id": ENV['google_client_id'],
            "access_token": user.token,
            "refresh_token": user.refresh_token,
            "scope": ENV['google_scopes'],
            "expiration_time_millis": user.token_expires_at
          }.to_json
        end
        def store(id, token)
          user = User.find(id)
          hsh = JSON.parse(token)
          user.update(
            token: hsh["access_token"],
            token_expires_at: hsh["expiration_time_millis"] / 1000
          )
        end
      end
    end
  end
end

根据自述文件自己实现

还可以使用自定义存储实现。有关其他详细信息,请参见token_store.rb。

通过上述文件的外观,用ActiveRecord(或另一个ORM)实现load(id)store(id, token)delete(id)应该不会太难。

上面接受的答案很好,我推荐它https://stackoverflow.com/a/48267763/473040,但我发现存储所有内容以备将来调试非常有用。简单也是美丽的:)

在Postgres DB表中添加json列(或在其他数据库中串行化文本字段)

class AddGooglePhotosTokensToUsers < ActiveRecord::Migration[7.0]
  def change
    add_column :users, :google_photo_tokens, :json
  end
end

类别:

class GoogleAuthDbStore < Google::Auth::TokenStore
  def load(id)
    user = User.find(id)
    user.google_photo_tokens
  end
  def store(id, tokens)
    user = User.find(id)
    user.google_photo_tokens = tokens
    user.save!
  end
  def delete id
    user = User.find(id)
    user.google_photo_tokens = nil
    user.save!
  end
end

使用

def authorizer
  return @authorizer if @authorizer
  client = Google::Auth::ClientId.new(Rails.application.credentials.google.fetch(:client_id), Rails.application.credentials.google.fetch(:client_secret))
  scope = ['https://www.googleapis.com/auth/photoslibrary.readonly']
  token_store =  Provider::GoogleAuthDbStore.new # <<<here
        
  @authorizer = Google::Auth::WebUserAuthorizer.new(client, scope, token_store, '/auth/google/callback')
  @authorizer
end

相关内容

  • 没有找到相关文章

最新更新