我正在尝试在我的应用程序中实现对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