※ 技術的に可能か調べただけなので、やる場合は自己責任でお願いします。
TwitterAPIのリクエスト制限を回避するために色々考えまして、タスクやユーザーごとにコンシューマーキーを切り替えられたらいいなと思いました。
omniauth-twitterについて
omniauth-twitter
は、omniauth
と併用することにより、Twitter認証を簡単にしてくれるgemです。コンシューマーキー等の設定は、以下のように書きます。
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, "consumer_key", "consumer_secret_key"
end
こうすることで/auth/twitter
にアクセスするとtwitter認証が走り、/auth/twitter/callback
にリダイレクトされごにょごにょと色々できるようになります。とても便利ですよね。
API制限の回避方法
TwitterAPIには、リクエスト数に制限があります。
作ったサービスのユーザー数が増えた時や、(APIリクエストの回数的な意味で)重い処理が走る場合にすぐに制限がかかってしまいます。そこで、 1アプリケーション内で複数のコンシューマーキーを利用することができないかと考えました。
request_path, callback_path の落とし穴
omniauth-twitterには、request_path
とcallback_path
なるものがあり、
<request_path>にアクセスすると、<callback_path>にリダイレクトされ、ごにょごにょできるようになるはず…なのですが、どうやらうまく動いてくれないようで、色んな方がこれに悩んでいました。
解決方法
path_prefixを使い振り分ける
path_prefixを使うと、/auth/twitter
となっていた/auth
の部分を他のパスに置き換えることができます。 例えば、path_prefix: "/hogehoge"
と設定すると、/hogehoge/twitter
にアクセスするとTwitter認証が走り、リダイレクト先が/hogehoge/twitter/callback
になります。これを用いて、どのコンシューマーキーでTwitter認証したかをルーティングパラメーターで判断し、Userモデルにそれを判別させるテーブルを用意してあげることで複数のコンシューマーキーをアプリ内で利用することが可能になりました。以下はその設定例になります。
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, Settings.twitter.alpha_consumer_key, Settings.twitter.alpha_consumer_secret_key, path_prefix: '/alpha'
provider :twitter, Settings.twitter.beta_consumer_key, Settings.twitter.beta_consumer_secret_key, path_prefix: '/beta'
provider :twitter, Settings.twitter.gamma_consumer_key, Settings.twitter.gamma_consumer_secret_key, path_prefix: '/gamma'
end
Rails.application.routes.draw do
get '/:type/:provider/callback', :to => 'sessions#callback'
post '/:type/:provider/callback', :to => 'sessions#callback'
# 省略
end
Class SessionsController < ApplicationController
skip_before_action :login_required, only: [:callback, :sign_in, :check]
def callback
auth = request.env['omniauth.auth']
user = User.find_by_provider_and_uid(auth['provider'], auth['uid']) || User.create_with_omniauth(auth)
user.update(api_type: params[:type])
redirect_to user_path(user.screen_name)
end
#省略
end
以上です。どなたかのお役に立てると幸いです。