覆盖 omniauth_callbacks_controller 中的 Devise 更新操作
overriding Devise update action inside omniauth_callbacks_controller
参考文献:
Rails 5.0.1
omniauth 1.8.1
omniauth-facebook 5.0.0
我有用户使用电子邮件+密码登录,其他用户使用 facebook 帐户登录。
主要问题是让 Facebook 的用户无需使用密码即可编辑自己的帐户,因为他们根本没有密码。 this post 中的解决方案,所以我可以添加这个 class:
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 登录,我会收到此错误消息:
The action 'facebook' could not be found for
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
以防其他人遇到类似问题。问题是 routes.rb
需要指定 both 被覆盖的控制器,例如:
devise_for :users, controllers: { registrations: 'registrations' , omniauth_callbacks: 'omniauth_callbacks' }
参考文献:
Rails 5.0.1
omniauth 1.8.1
omniauth-facebook 5.0.0
我有用户使用电子邮件+密码登录,其他用户使用 facebook 帐户登录。
主要问题是让 Facebook 的用户无需使用密码即可编辑自己的帐户,因为他们根本没有密码。 this post 中的解决方案,所以我可以添加这个 class:
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 登录,我会收到此错误消息:
The action 'facebook' could not be found for 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
以防其他人遇到类似问题。问题是 routes.rb
需要指定 both 被覆盖的控制器,例如:
devise_for :users, controllers: { registrations: 'registrations' , omniauth_callbacks: 'omniauth_callbacks' }