Google API を Ruby から操作するための Google 製 gem が googleauth で、これは当然 OAuth2 のトークンをファイルや DB に保存しておくように作られているが、中に含まれているトークン保存のためのクラス (TokenStore) は以下の2種類しかなくて、つまり ActiveRecord 用の TokenStore は用意されていない。
- FileTokenStore (https://github.com/googleapis/google-auth-library-ruby/blob/master/lib/googleauth/stores/file_token_store.rb)
- RedisTokenStore (https://github.com/googleapis/google-auth-library-ruby/blob/master/lib/googleauth/stores/redis_token_store.rb)
だけど、上記 2 クラスは Google::Auth::TokenStore https://github.com/googleapis/google-auth-library-ruby/blob/master/lib/googleauth/stores/redis_token_store.rb を継承しているようだったので、雑に継承して通せたのでメモ。
これから作るのは、
- GoogleAuthToken ( token_key と client_id の組をもつ Model )
- ActiveRecordTokenStore ( Google::Auth::TokenStore のサブクラスで、 ActiveRecord 用 )
$ rails generate model google_auth_token token_key:string client_id:string
class GoogleAuthToken < ApplicationRecord
belongs_to :user #これは任意だけど、ふつうこういう形になるんじゃないかな
validates :token_key, presence: true, uniqueness: true
validates :client_id, presence: true
end
app/models/active_record_token_store.rb
に、
class ActiveRecordTokenStore < Google::Auth::TokenStore
def initialize user_id
@user_id = user_id
end
def load id
record = GoogleAuthTokenStore.find_by! user_id: @user_id, token_key: id
record.to_json
end
def store id, token
json = JSON.parse(token)
client_id = json["client_id"]
access_token = json["access_token"]
refresh_token = json["refresh_token"]
expiration_time_millis = json["expiration_time_millis"]
record = GoogleAuthToken.find_or_initialize_by user_id: @user_id, token_key: id, client_id: client_id, access_token: access_token, refresh_token: refresh_token, expiration_time_millis: expiration_time_millis
record.save
end
def delete id
record = GoogleAuthToken.find_by! user_id: @user_id, token_key: id
record.destroy
end
end
こんな感じにしておけば、例えば
def authorize client_id, token_store
Google::Auth::UserAuthorizer.new client_id, [
Google::Apis::DriveV3::AUTH_DRIVE,
], token_store
end
とすると、 API アクセスしやすい。