覆盖omniauth_callbacks_controller中的Devise更新操作

时间:2018-08-01 13:10:23

标签: ruby-on-rails devise omniauth

参考文献:

Rails 5.0.1
omniauth 1.8.1
omniauth-facebook 5.0.0

我有用户使用电子邮件+密码登录,其他用户使用Facebook帐户登录。

主要问题是让Facebook用户无需使用密码即可编辑自己的帐户,因为他们没有密码。 example中的解决方案,因此我可以添加此类:

  def update
    if current_user.provider == "facebook"
      params.delete("current_password")
      resource.update_without_password(user_params)
    else
      resource.update_with_password(user_params)
    end
    redirect_to root_path
  end

所以我有这个:

routes.br

devise_for :users, controllers: { omniauth_callbacks: "omniauth_callbacks" }

omniauth_callbacks_controller.rb 中,我添加了此update函数:

class OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def update
    if current_user.provider == "facebook"
      params.delete("current_password")
      resource.update_without_password(user_params)
    else
      resource.update_with_password(user_params)
    end
    redirect_to root_path
  end

  def facebook
    user = User.find_for_facebook_oauth(request.env['omniauth.auth'])
    if user.persisted?
      sign_in user
      redirect_to root_path
      set_flash_message(:notice, :success, kind: 'Facebook') if is_navigational_format?
    else
      session['devise.facebook_data'] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end

  def user_params
    params.require(:user).permit(:first_name, :last_name, :phone, :picture, :facebook_picture_url)
  end

end

问题是设备不读取此功能。因此,如果我们在其中添加Byebug,它将不会在那里停止。

覆盖此更新功能的唯一方法是在下面添加此配置。

routes.br

devise_for :users, controllers: { registrations: 'registrations' }

registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController

  def update
    if current_user.provider == "facebook"
      params.delete("current_password")
      resource.update_without_password(user_params)
    else
      resource.update_with_password(user_params)
    end
    redirect_to root_path
  end

  def facebook
    user = User.find_for_facebook_oauth(request.env['omniauth.auth'])
    if user.persisted?
      sign_in user
      redirect_to root_path
      set_flash_message(:notice, :success, kind: 'Facebook') if is_navigational_format?
    else
      session['devise.facebook_data'] = request.env['omniauth.auth']
      redirect_to new_user_registration_url
    end
  end

  def user_params
    params.require(:user).permit(:first_name, :last_name, :phone, :picture, :facebook_picture_url)
  end

end

第二种方法的唯一问题是,如果我尝试使用Facebook登录,则会收到以下错误消息:

  

找不到操作“ facebook”   Devise :: OmniauthCallbacksController

我的设计配置:

devise.rb

Devise.setup do |config|

  config.omniauth :facebook, ENV["FB_ID"], ENV["FB_SECRET"],
    scope: 'email',
    info_fields: 'email, first_name, last_name',
    image_size: 'large',  # 50x50, guaranteed ratio
    secure_image_url: true

...

end

1 个答案:

答案 0 :(得分:1)

以防万一其他人有类似的问题。问题是routes.rb需要指定要覆盖的控制器的两者,例如:

devise_for :users, controllers: { registrations: 'registrations' , omniauth_callbacks: 'omniauth_callbacks' }