2013-03-14 1 views
0

Я разрабатываю монтируемый движок (называемый SimpleUser), который использует Devise, OmniAuth и OmniAuth-Facebook. Сначала я сделал тестовое приложение с драгоценными камнями, и каждый работал нормально. Затем я начал строить движок с нуля, используя пример тестового приложения в качестве примера.Обратный вызов Omniauth-Facebook не инициализируется в Rails Mountable Engine

Все почти выполнено, за исключением связи с Facebook (он использует всплывающее окно Javascript). Когда я нажимаю «войти» отображается всплывающее окно FB, я предоставить приложение, он перенаправляет на маршрут указанного (см маршрутов), но выдает эту ошибку:

NoMethodError in SimpleUser::AuthController#create 
undefined method `[]' for nil:NilClass 

Ошибка возникает в том, что действия, в строка authentication = Authentication.find_by_provider_and_uid(auth['provider'], auth['uid']), где auth is nil (auth происходит от auth = request.env["omniauth.auth"]).

Одна вещь, которую я проверяю, это то, что фаза обратного вызова не инициализирована. Это журнал тестового приложения:

Started GET "/auth/facebook/callback" for 127.0.0.1 at 2013-03-14 08:52:56 -0600 (facebook) Callback phase initiated. Processing by AuthController#create as HTML Parameters: {"provider"=>"facebook"}

Это журнал приложения двигателя:

Started GET "/simple_user/auth/facebook/callback" for 127.0.0.1 at 2013-03-14 08:51:19 -0600 
Processing by SimpleUser::AuthController#create as HTML 
    Parameters: {"provider"=>"facebook"} 

Для управления OmniAuth я добавил драгоценный камень в .gemspec и к Gemfile; Кроме того, мне нужны драгоценные камни в двигателе, и в генераторе двигателя я перемещаю шаблон omniauth.rb в config/initializers родительского приложения во время установки. Это то, что у меня есть:

AuthController (находится в приложении/Контроллеры/simple_user/auth_controller.rb)

module SimpleUser 
    class AuthController < ApplicationController 

    def create 
     auth = request.env["omniauth.auth"] 
     authentication = Authentication.find_by_provider_and_uid(auth['provider'], auth['uid']) 

     if authentication 
     flash[:notice] = "Signed in successfully." 
     sign_in(:user, authentication.user) 
     redirect_to root_url 
     else 
     user = User.build_new_auth(auth) 
     #user.apply_omniauth(auth) 
     if user.save(:validate => false) 
      flash[:notice] = "Account created and signed in successfully." 
      sign_in(:user, user) 
      redirect_to root_url 
     else 
      flash[:error] = "Error while creating the user account. Please try again." 
      redirect_to root_url 
     end 
     end 
    end 

    end 
end 

Двигатель

module SimpleUser 

    require 'rubygems' 
    require 'devise' 
    require 'cancan' 
    require 'rolify' 
    require 'omniauth' 
    require 'omniauth-facebook' 
    require 'simple_form' 

    class Engine < ::Rails::Engine 
    isolate_namespace SimpleUser 

    config.before_configuration do 
     env_file = File.join(Rails.root, 'config', 'fb_config.yml') 
     YAML.load(File.open(env_file)).each do |key, value| 
     ENV[key.to_s] = value.to_s 
     end if File.exists?(env_file) 

     env_file = File.join(Rails.root, 'config', 'devise_config.yml') 
     YAML.load(File.open(env_file)).each do |key, value| 
     ENV[key.to_s] = value.to_s 
     end if File.exists?(env_file) 
    end 
    end 
end 

Генератор

module SimpleUser 
    module Generators 
    class InstallGenerator < ::Rails::Generators::Base 
     source_root File.expand_path("../templates", __FILE__) 
     desc "Install SimpleUser" 

     def copy_config_file 
     copy_file "fb_config.yml", "config/fb_config.yml" 
     copy_file "devise_config.yml", "config/devise_config.yml" 
     copy_file "omniauth.rb", "config/initializers/omniauth.rb" 
     end 

     def copy_migrations 
     rake "simple_user:install:migrations" 
     SimpleUser::Engine.load_seed 
     end 

    end 
    end 
end 

Шаблон omniauth.rb

require 'omniauth' 
require 'omniauth-facebook' 

OmniAuth.config.logger = Rails.logger 

Rails.application.config.middleware.use OmniAuth::Builder do 
    provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], :scope => ENV['FACEBOOK_SCOPE'] 
end 

Маршруты (на двигателе)

match 'auth/:provider/callback', to: 'auth#create' 
match 'auth/failure', to: redirect('/') 

Маршруты (на фиктивной приложение)

mount SimpleUser::Engine => "/simple_user", :as => "simple_user" 

.gem спецификации зависимости

s.add_dependency "rails", "~> 3.2.12" 
    s.add_dependency "devise" 
    s.add_dependency "cancan" 
    s.add_dependency "rolify" 
    s.add_dependency "omniauth" 
    s.add_dependency "omniauth-facebook", "1.4.1" 
    s.add_dependency "simple_form" 

    #s.add_development_dependency "mysql2" 
    s.add_development_dependency "sqlite3" 
    s.add_development_dependency "jquery-rails" 
    s.add_development_dependency "debugger" 

Gemfile

source "http://rubygems.org" 

gemspec 

gem 'devise' 
gem 'cancan' 
gem 'rolify' 
gem 'omniauth' 
gem 'omniauth-facebook', '1.4.1' 
gem 'simple_form' 

# Development 
gem 'jquery-rails' 
gem 'debugger' 

Я думаю, что проблема обратного вызова, которая не инициализируется, и причина может быть, что OmniAuth не загружалась, но я не знать, если это так и как его решить.

Вы можете проверить проект в https://github.com/pablomarti/simple_user, и если вы хотите его клонировать и проверить, вы можете использовать генератор rails g simple_user:install, и вы можете увидеть код test/dummy, чтобы получить представление об этом.

спасибо, что заранее.

ответ

0

Раствор для удаления omniauth.rb и включает в себя промежуточное программном обеспечении от OmniAuth в двигателе, так что двигатель выглядит следующим образом:

module SimpleUser 

    require 'rubygems' 
    require 'devise' 
    require 'cancan' 
    require 'rolify' 
    require 'omniauth' 
    require 'omniauth-facebook' 
    require 'simple_form' 

    class Engine < ::Rails::Engine 
    isolate_namespace SimpleUser 

    middleware.use OmniAuth::Builder do 
     provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'], :scope => ENV['FACEBOOK_SCOPE'] 
    end 

    config.before_configuration do 
     env_file = File.join(Rails.root, 'config', 'fb_config.yml') 
     YAML.load(File.open(env_file)).each do |key, value| 
     ENV[key.to_s] = value.to_s 
     end if File.exists?(env_file) 

     env_file = File.join(Rails.root, 'config', 'devise_config.yml') 
     YAML.load(File.open(env_file)).each do |key, value| 
     ENV[key.to_s] = value.to_s 
     end if File.exists?(env_file) 
    end 

    end 
end 

Спасибо Дмитрия Лихачев за ответ https://stackoverflow.com/a/8413724/347501 в подобных проблемах.