使用 Devise 和 Omniauth 编辑用户 [英] Editing Users With Devise and Omniauth

查看:25
本文介绍了使用 Devise 和 Omniauth 编辑用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过 Railscast 实施 Devise 和 OmniAuth(以及 Devise documentation) -- 目前,我有一个网站可供访问者使用他们的 Facebook 帐户或填写表格进行注册.

I'm working through the Railscast on implementing Devise and OmniAuth (along with the Devise documentation) -- currently, I've got a site going where visitors can sign up using their facebook accounts or by filling out a form.

不过,当通过 OmniAuth 注册的用户尝试编辑他们的个人资料时,我遇到了麻烦.当用户提交对其个人资料的更改时,Devise 会查找用户的当前密码,但使用 facebook 登录的用户不知道他们的密码(它们在用户模型中自动设置):

I'm running into trouble when users that sign up via OmniAuth try to edit their profiles, though. Devise looks for the user's current password when they submit changes to their profiles, but those that logged in with facebook don't know their passwords (they're set automatically in the user model):

  def self.find_for_facebook_oauth(auth, signed_in_resource=nil)
    user = User.where(:provider => auth.provider, :uid => auth.uid).first
    unless user
      user = User.create(first_name:auth.extra.raw_info.first_name,
                         last_name:auth.extra.raw_info.last_name,
                           provider:auth.provider,
                           uid:auth.uid,
                           email:auth.info.email,
                           password:Devise.friendly_token[0,20]
                           )
    end
    user
  end

当用户编辑他的信息时,如果他通过 OmniAuth 设置他的帐户,应用程序应该不需要密码确认.该教程建议使用方便的 password_required?方法将帮助我实现这个结果.具体来说,将这个方法添加到用户模型意味着它应该只在用户没有通过 OmniAuth 注册时才返回 true(在这种情况下 provider 属性将为 nil):

When a user edits his information, the app should not require password confirmation if he set up his account through OmniAuth. The tutorial suggests that the handy password_required? method will help me achieve this outcome. Specifically, adding this method to the user model means that it should only return true if the user didn't sign up through OmniAuth (the provider attribute would be nil in that case):

def password_required?
  super && provider.blank?
end

因此,一段代码如下:

<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
  <%= devise_error_messages! %>
    <%= render :partial => "essential_user_info_inputs", :locals => { :f => f } %>
    <%= render :partial => "inessential_user_info_inputs", :locals => { :f => f } %>
    <% if f.object.password_required? %> 
        <%= render :partial => "password_inputs", :locals => { :f => f } %>
        <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
        <%= f.password_field :current_password %>
    <% end %>
  <%= f.submit "Update" %>
<% end %>

理论上只会在需要时显示密码输入.它还表明,Devise 内置了逻辑,说 OmniAuth 用户不需要使用密码来编辑他们的帐户.我不知道这是否属实,但教程看起来像那样.但是当 OmniAuth 用户尝试编辑他的帐户时,我得到当前密码不能为空".非 OmniAuth 用户也是如此(这是有道理的,因为密码字段也不会显示在这些用户的编辑页面上).

would theoretically only display password inputs when needed. It also suggests that Devise has built in logic saying that OmniAuth users don't need to use passwords to edit their accounts. I have no idea if this is true, but the tutorial kind of makes it look like that. But when an OmniAuth user tries to edit his account, I get "Current password can't be blank." Same thing with non-OmniAuth users (this makes sense, since the password fields don't show up on those users' edit pages either).

一些探查确认密码需要?方法在用户通过 OmniAuth 和网站的常规用户注册时都返回 false.即使我将其更改为简单地运行超类方法,它也会返回 false.

Some poking around confirms that the password_required? method is returning false, both when the user signed up through OmniAuth and through the site's regular user signup. Even when I change it to simply run the superclass method, it returns false.

对 password_required 方法有什么想法吗?我在任何地方都找不到关于它的任何信息,但我觉得这就是现在的绊脚石.

Any ideas of what's going on with the password_required method? I can't find anything about it anywhere, but I feel like that's what's tripping things up right now.

这现在可以工作了,但没有使用 Railscast 中概述的方法,该方法依赖于 requires_password?方法,一个我仍然一无所知的话题.相反,我实施了概述的解决方案 此处,如建议的此处一>.所以我现在只需要密码来使用代码更新非 OmniAuth 帐户:

This is now working, but not using the method outlined in the Railscast, which relies on requires_password? method, a topic that I still know nothing about. Instead, I implemented the solution outlined here, as suggested here. So I am now only requiring passwords to update non-OmniAuth accounts with the code:

class Users::RegistrationsController < Devise::RegistrationsController
def update
    @user = User.find(current_user.id)
    email_changed = @user.email != params[:user][:email]
    is_facebook_account = !@user.provider.blank?

    successfully_updated = if !is_facebook_account
      @user.update_with_password(params[:user])
    else
      @user.update_without_password(params[:user])
    end

    if successfully_updated
      # Sign in the user bypassing validation in case his password changed
      sign_in @user, :bypass => true
      redirect_to root_path
    else
      render "edit"
    end
  end
end

推荐答案

最简单的方法是覆盖 RegistrationsController 中的 update_resource 方法.这是由设计在他们自己的控制器实现中建议的:

The easiest way is to overwrite the update_resource method in your RegistrationsController. This is advised by devise in their own implementation of the controller:

  # By default we want to require a password checks on update.
  # You can overwrite this method in your own RegistrationsController.
  def update_resource(resource, params)
    resource.update_with_password(params)
  end

所以解决方案是在你自己的控制器中像这样覆盖这个方法:

So the solution is to overwrite this method in your own controller like this:

class Users::RegistrationsController < Devise::RegistrationsController

  # Overwrite update_resource to let users to update their user without giving their password
  def update_resource(resource, params)
    if current_user.provider == "facebook"
      params.delete("current_password")
      resource.update_without_password(params)
    else
      resource.update_with_password(params)
    end
  end

end

这篇关于使用 Devise 和 Omniauth 编辑用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆