【问题标题】:OmniAuth::NoSessionError - You must provide a session to use OmniAuth. (configured in devise)OmniAuth::NoSessionError - 您必须提供会话才能使用 OmniAuth。 (在设计中配置)
【发布时间】:2014-11-14 03:18:24
【问题描述】:

您好,我正在学习如何使用 omniauth 作为 ember 应用的后端。

当我运行我的应用程序时,我得到下面提到的错误 OmniAuth::NoSessionError - 您必须提供会话才能使用 OmniAuth

在重新启动轨道上,我的应用程序在下一行停止。

  172: def call!(env) # rubocop:disable CyclomaticComplexity
    173:   unless env['rack.session']
    174:     error = OmniAuth::NoSessionError.new('You must provide a session to use OmniAuth.')
 => 175:     fail(error)
    176:   end
    177: 

配置/初始化器/设计

Devise.setup do |config|

  config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
  require 'devise/orm/active_record'
  config.case_insensitive_keys = [ :email ]
  config.strip_whitespace_keys = [ :email ]
  config.http_authenticatable = true
  config.skip_session_storage = [:http_auth]
  config.stretches = Rails.env.test? ? 1 : 10
  config.reconfirmable = true
  config.expire_all_remember_me_on_sign_out = true
  config.password_length = 8..128
  config.reset_password_within = 6.hours
  config.http_authenticatable_on_xhr = false
  config.navigational_formats = ['*/*', :html,:json]
  config.sign_out_via = :delete
  require 'omniauth-facebook'
  config.omniauth :facebook, ENV['8987087080'] , ENV['3d6a359a37c8780870dxxxx5'],:strategy_class => OmniAuth::Strategies::Facebook
end

config/initializer/session_store.rb

Rails.application.config.session_store :disabled

routes.rb

Rails.application.routes.draw do

  namespace :api do
    namespace :v1 do
      resources :users
      resources :games
    end
  end

  ActiveAdmin.routes(self)
  #devise_for :admin_users, ActiveAdmin::Devise.config
  devise_for :users, controllers: { 
    omniauth_callbacks: 'omniauth_callbacks',
    sessions: 'sessions' , 
    registrations: "registrations",


  }
   devise_scope :user do 
    match 'users/sign_in', to: 'sessions#create', via: :post
    match 'api/v1/users' , to: 'registrations#create' , via: :post
  end

end

gemfile.rb

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.1.6'

platforms :ruby do # linux
  gem 'unicorn'
  gem 'foreman'
  gem 'delayed_job_active_record'
end
group :development, :test do
    gem 'compass'
    gem 'pry'
    gem 'pry-remote'
    gem 'pry-rails'
    gem 'pry-rescue'
    gem 'pry-stack_explorer'
    gem 'pry-byebug'
    gem 'guard'
    gem 'guard-livereload'
    gem 'guard-rails'
    gem 'guard-rspec'
    gem 'guard-cucumber'
    gem 'guard-zeus'
    gem 'rspec-rails'

end
group :production do
    #gem 'pg'
end

#authentication
gem 'cancan'
gem 'rolify'
gem 'devise'
gem 'omniauth'
gem 'omniauth-facebook', '=1.4.0'
gem 'oauth2'



# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'
gem 'bootstrap-sass', '~> 3.1.1'
gem 'bootswatch-rails'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'



# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'


group :doc do
  # bundle exec rake doc:rails generates the API under doc/api.
  gem 'sdoc', require: false
end

#ember
gem "active_model_serializers"
gem "ember-source", "~>1.7.0"

#asyc http calls
gem 'hashie_rails'
gem "typhoeus"
gem "virtus"

#middleware
gem "rack-cors", require: 'rack/cors'



platforms :mswin do 
  gem "wdm", :group => [:development, :test]
end
#gem 'wdm', '>= 0.1.0'

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin]

【问题讨论】:

    标签: ruby-on-rails devise omniauth


    【解决方案1】:

    这是因为您禁用了会话中间件(查看rake middleware 的输出)。如果没有会话中间件,Omniauth 将无法工作。

    你在这里禁用了它:Rails.application.config.session_store :disabled

    如果您因为除了 Omniauth 之外不使用会话而试图放弃会话,那么您唯一能做的就是编写自己的中间件,注入 ActionDispatch::Session::CookieStore 和可能的其他必要中间件基于 URL(即,如果 URL 是 /auth/*)。这是我用来实现此目的的示例(仅在 URL 路径不是 /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
    

    在此示例中,我仅在 URL /api/ 开头时启用会话中间件。当然,您仍然需要删除 Rails.application.config.session_store :disabled 并正确设置会话存储。在我的示例中,我使用 cookie 存储。您可能需要根据rake middleware 中缺少的中间件来调整我的示例。但是,如果您出于性能原因不这样做,那么只需重新启用会话中间件即可。

    【讨论】:

    • 列出中间件的控制台命令是rake middleware 而不是rack middleware
    • 如果您有一个“仅限 API”的应用程序,并且您还想在其上粘贴一个简单的 /admin CRUD UI,这也是一项很棒的技术。
    【解决方案2】:

    进入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
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多