ログインする時は、間口を広げるため緩い権限で、必要なときに追加で認証させたい、というニーズはわりとある。
でもOmniAuthはScopeをinitializerで指定しちゃうよなぁ、どうするのかな、と思ってたら、Setup Phase なるものがちゃんと用意されてた。知らなかった…。
例)Public Onlyでログインして、後からGistの権限を要求する
まじめにやる場合は、http://www.createdbypete.com/articles/dynamic-omniauth-provider-setup/ みたいに、Rackアプリを作るのが綺麗っぽい。
ここでは、手を抜いて、SessionsController#setup
を使う。(参考:http://mikepackdev.com/blog_posts/2-dynamically-requesting-facebook-permissions-with-omniauth)
config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :github, ENV['GITHUB_CLIENT_ID'], ENV['GITHUB_CLIENT_SECRET'], setup: true # setup: trueが必要
end
cat config/routes.rb
get '/auth/:provider/callback', to: 'sessions#create'
get '/auth/:provider/setup', to: 'sessions#setup' # いつものに加えてこの行を追加
app/controllers/sessions_controller.rb
def create
# 他の処理
# TODO: もっと綺麗な条件で分岐したい
if request.env['omniauth.params'].try(:[], 'scope') == 'gist'
# gist向けの処理
end
# 他の処理
end
def setup
if params[:scope] == 'gist'
# 今回は元のscopeが無しなので単純に代入
request.env['omniauth.strategy'].options[:scope] = 'gist'
end
render nothing: true, status: 404 # setupで404を返せばその後の処理はいつも通りやってくれる
end
これで、
/auth/github
はscope無しの認証/auth/github?scope=gist
はGistの権限を要求
が実現できた。