【问题标题】:Devise + omniauth twitter + authentications table设计 + omniauth 推特 + 身份验证表
【发布时间】:2014-09-26 05:33:26
【问题描述】:

当我通过我的 twitter 登录按钮进行身份验证时,我收到了这个浏览器错误

The action 'new' could not be found for RegistrationsController

根据本指南http://www.orhancanceylan.com/rails-twitter-and-facebook-authentications-with-omniauth-and-devise/#comment-1375,我创建了一个registrations_controller.rb 来覆盖设计控制器的某些方法

很抱歉对代码进行了详细说明。主要部分在twitter 方法中的authentications_controller.rb 中,在方法的else 部分中。

当用户没有之前创建的其他第 3 方登录身份验证且未通过设计登录时,该部分代码控制。因此,必须在该部分代码中创建身份验证记录和用户记录。但我得到了错误。

有一个身份验证表,以便我可以添加其他omniauth 策略。

如果不清楚或需要更多信息,请告诉我如何改进问题。

routes.rb

  devise_for :users, :path => '', 
                     :path_names => { :sign_in => "login", 
                                      :sign_out => "logout", 
                                      :sign_up => "sign-up", 
                                      :account_update => "account-settings" },
                     :controllers => { omniauth_callbacks: "authentications", registrations: "registrations" }

  get "/auth/:provider/callback", to: "authentications#:provider"

authentications_controller.rb

class AuthenticationsController < Devise::OmniauthCallbacksController

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

    if authentication 
      # If already registered previously
      flash[:notice] = "Logged in successfully."      
      user = User.find(authentication.user_id)
      sign_in_and_redirect user
    elsif current_user 
      # If signed in via any other strategy, including devise.

      current_user.authentications.create!(:provider => omni['provider'], 
                                           :uid => omni['uid'], 
                                           :token => token = omni['credentials']['token'],
                                           :token_secret => omni['credentials']['secret'])
      flash[:notice] = "Authentication successful."
      sign_in_and_redirect current_user
    else                                     # this is the conditional that gets executed.
      # If brand new to the site.
      user = User.new
      user.apply_omniauth(omni)

      if user.save
        flash[:notice] = "Login successful."
        sign_in_and_redirect User.find(user.id)
      else
        session[:omniauth] = omni.except('extra')
        redirect_to new_user_registration_path
      end
    end

  end

  # Overrides
  def create
    super
    session[:omniauth] = nil unless @user.new_record?
  end

end

authentication.rb

# == Schema Information
#
# Table name: authentications
#
#  id           :integer          not null, primary key
#  user_id      :integer
#  provider     :string(255)
#  uid          :string(255)
#  token        :string(255)
#  token_secret :string(255)
#  profile_page :string(255)
#  created_at   :datetime
#  updated_at   :datetime
#

class Authentication < ActiveRecord::Base
  belongs_to :user
end

#

user.rb

# == Schema Information
#
# Table name: users
#
#  id                     :integer          not null, primary key
#  created_at             :datetime
#  updated_at             :datetime
#  email                  :string(255)      default(""), not null
#  encrypted_password     :string(255)      default(""), not null
#  reset_password_token   :string(255)
#  reset_password_sent_at :datetime
#  remember_created_at    :datetime
#  sign_in_count          :integer          default(0), not null
#  current_sign_in_at     :datetime
#  last_sign_in_at        :datetime
#  current_sign_in_ip     :inet
#  last_sign_in_ip        :inet
#  username               :string(255)
#  admin                  :boolean          default(FALSE)
#  image                  :string(255)
#  points                 :integer          default(0), not null
#  hacks_count            :integer          default(0), not null
#  comment_threads_count  :integer          default(0), not null
#
# Indexes
#
#  index_users_on_email                 (email) UNIQUE
#  index_users_on_reset_password_token  (reset_password_token) UNIQUE

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, 
         :omniauthable, omniauth_providers: [ :twitter ]

  has_many :hacks
  has_many :comments
  acts_as_voter

  has_many :authentications

  validates :username,
            presence: true,
            :uniqueness => { case_sensitive: false },
            length: { in: 4..20 }

#

  SOCIALS = {
    twitter:  'Twitter',
    facebook: 'Facebook'
  }

#


  def apply_omniauth(omni)
    authentications.build(:provider => omni['provider'],
                          :uid => omni['uid'],
                          :token => token = omni['credentials']['token'],
                          :token_secret => omni['credentials']['secret'])
  end

  # Overrides
  def update_with_password(params, *options)
    if encrypted_password.blank?
      update_attributes(params, *options)
    else
      super
    end
  end

  def password_required?
    super && (authentications.empty? || !password.blank?)
  end

end

【问题讨论】:

  • 你能提供错误堆栈吗?

标签: ruby-on-rails ruby-on-rails-4 devise omniauth


【解决方案1】:

我从错误的控制器继承了registrations_controller。

应该是

class RegistrationsController &lt; Devise::RegistrationsController

不是

class RegistrationsController &lt; ApplicationController

注意,伙计们 =]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    相关资源
    最近更新 更多