OmniAuth::NoSessionError - You must provide a session to use OmniAuth. (configured in devise)

最后都变了- 提交于 2019-12-03 02:26:55

It is because you disabled the session middleware (look at the output of rake middleware). Omniauth will not work without the session middleware.

You disabled it here: Rails.application.config.session_store :disabled

If you are trying to ditch session because you do not use it other than for Omniauth, then the only thing you can do is write your own middleware that injects ActionDispatch::Session::CookieStore and possibly other necessary middlewares based on the URL (i.e. if the URL is /auth/*). Here is an example of what I use to achieve this (only uses session if URL path is not /api/...):

# /config/application.rb
config.middleware.insert_before ActionDispatch::ParamsParser, "SelectiveStack"

# /config/initializers/omniauth.rb
::OmniAuthConfig = Proc.new do
  provider :github, # ...
end

# /app/middleware/selective_stack.rb
class SelectiveStack
  def initialize(app)
    @app = app
  end

  def call(env)
    if env["PATH_INFO"].start_with?("/api/") # <--- Change URL path here
      @app.call(env)
    else
      middleware_stack.build(@app).call(env)
    end
  end

private
  def middleware_stack
    @middleware_stack ||= begin
      ActionDispatch::MiddlewareStack.new.tap do |middleware|
        # needed for OmniAuth
        middleware.use ActionDispatch::Cookies
        middleware.use Rails.application.config.session_store, Rails.application.config.session_options
        middleware.use OmniAuth::Builder, &OmniAuthConfig
        # needed for Doorkeeper /oauth views
        middleware.use ActionDispatch::Flash
      end
    end
  end
end

In this example I only enable the session middleware when the URL does not start with /api/. You will still need to remove Rails.application.config.session_store :disabled and properly set up your session store, of course. In my example I use the cookie store. You might need to tweak my example based on which middleware you are missing in rake middleware. But if you're not doing this for performance reasons then just reenable the session middleware.

Into application.rb

...

config.api_only = true
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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!