こんにちは!kossyです!
さて、今回はRails APIモードでomniauth導入時に「OmniAuth::NoSessionError (You must provide a session to use OmniAuth.)」が出る場合の対処法をブログに残してみたいと思います。
ActionDispatchミドルウェアを導入する
RailsのAPIモードの場合、セッションやcookie等のミドルウェアがデフォルトでインストールされません。
omniauthを使う場合、セッションのミドルウェアは必須になるため、ActionDispatchミドルウェアを導入する必要があります。
application.rbを以下のように編集してください。
module SampleApi class Application < Rails::Application config.load_defaults 6.0 config.api_only = true # ↓追加↓ # For Omniauth config.session_store :cookie_store, key: '_interslice_session' config.middleware.use ActionDispatch::Cookies # Required for all session management config.middleware.use ActionDispatch::Session::CookieStore, config.session_options # ↑ここまで↑ end
omniauthのエラー定義を見てみる
OmniAuth::NoSessionErrorの処理の中身を見に行ってみます。
omniauth/strategy.rb at master · omniauth/omniauth · GitHub
# The logic for dispatching any additional actions that need # to be taken. For instance, calling the request phase if # the request path is recognized. # # @param env [Hash] The Rack environment. def call!(env) # rubocop:disable CyclomaticComplexity, PerceivedComplexity unless env['rack.session'] error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.') raise(error) end @env = env warn_if_using_get_on_request_path @env['omniauth.strategy'] = self if on_auth_path? return mock_call!(env) if OmniAuth.config.test_mode begin return options_call if on_auth_path? && options_request? return request_call if on_request_path? && OmniAuth.config.allowed_request_methods.include?(request.request_method.downcase.to_sym) return callback_call if on_callback_path? return other_phase if respond_to?(:other_phase) rescue StandardError => e raise e if env.delete('omniauth.error.app') return fail!(e.message, e) end @app.call(env) end
重要なのはこの箇所ですね。
unless env['rack.session'] error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.') raise(error) end
env['rack.session'] がfalseの場合、OmniAuth::NoSessionErrorをraiseしています。
まとめ
そもそも env['rack.session'] ってなんやねんな状態なので、近々 ActionDispatch周りのミドルウェアも含めて、コードリーディング記事を書くと思います。