Devise - Omniauth - 如果用户通过Facebook登录,隐藏密码字段 [英] Devise - Omniauth – Hiding password fields if the user is signed in through Facebook

查看:248
本文介绍了Devise - Omniauth - 如果用户通过Facebook登录,隐藏密码字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Devise与Omniauth我成功地允许用户使用他们的Facebook帐户登录。在Omniauth wiki 我也可以禁止在编辑帐户时输入密码。



目前我遇到的问题在我的注册#edit 视图中隐藏密码字段,如果他们通过Facebook注册。作为两个宝石的新手,我还在努力调整。所以,当谈到设置必要的帮助方法时,我会很失望。



按照wiki的指示,这里是我的注册控制器的外观如:

  class RegistrationsController< Devise :: RegistrationsController 
before_filter:configure_permitted_pa​​rameters,如果::devise_controller?

def update
@user = User.find(current_user.id)

successfully_updated = if needs_password?(@ user,params)
@user .update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
else
#删除虚拟current_password属性
#update_without_password不知道如何忽略它
params [:user]。 delete(:current_password)
@ user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
end

如果success_updated
set_flash_message:notice,,updated
#登录用户绕过验证,以防其密码更改
sign_in @user,:bypass => true
redirect_to after_update_path_for(@user)
else
呈现edit
end
end

private

#检查我们是否需要密码来更新用户数据
#ie如果密码或电子邮件被更改
#根据需要扩展这个
def needs_password?(user,params)
用户。 email!= params [:user] [:email] ||
params [:user] [:password] .present? ||
params [:user] [:password_confirmation] .present?
end

protected

def configure_permitted_pa​​rameters
devise_parameter_sanitizer.for(:sign_up)do | u |
u.permit(:first_name,:last_name,:email,:password,:password_confirmation)
end
devise_parameter_sanitizer.for(:account_update)do | u |
u.permit(:first_name,:last_name,:email,:password,:password_confirmation)
end
end
end
/ pre>

这里是我的注册#编辑视图:

 <%提供:标题,'编辑个人资料'%> 

< h2>编辑<%= resource_name.to_s.humanize%>< / h2>

<%= form_for(resource,as:resource_name,url:registration_path(resource_name),html:{method::put})do | f | %GT;
<%= devise_error_messages! %GT;

< div><%= f.label:first_name%>< br />
<%= f.text_field:first_name%>< / div>

< div><%= f.label:last_name%>< br />
<%= f.text_field:last_name%>< / div>

< div><%= f.label:email%>< br />
<%= f.email_field:email%>< / div>

<%if devise_mapping.confirmable? &安培;&安培; resource.pending_reconfirmation? %GT;
< div>目前等待确认:<%= resource.unconfirmed_email%>< / div>
<%end%>

< div><%= f.label:password%> < i>(如果不想更改则为空)< / i>< br />
<%= f.password_field:password,autocomplete:off%>< / div>

< div><%= f.label:password_confirmation%>< br />
<%= f.password_field:password_confirmation,autocomplete:off%>< / div>

< div><%= f.label:current_password%> < i(我们需要您当前的密码来确认您的更改)< / i>< br />
<%= f.password_field:current_password,autocomplete:off%>< / div>

< div><%= f.submit更新%>< / div>
<%end%>

更新



经过广泛的研究,我找到了一个 问题 根据隐藏输入字段(第二个是问题中的最后一个注释),我自己正在寻找什么。唯一的问题是,由于某些原因,它会触发密码验证错误,尽管它不在...

 < div> 
<%= f.label:first_name%>< br />
<%= f.text_field:first_name%>
< / div>

< div>
<%= f.label:last_name%>< br />
<%= f.text_field:last_name%>
< / div>

<%if user_signed_in? &安培;&安培; !current_user.provider =='facebook'%>
< div>
<%= f.label:email%>< br />
<%= f.email_field:email%>
< / div>

<%if devise_mapping.confirmable? &安培;&安培; resource.pending_reconfirmation? %GT;
< div>目前等待确认:<%= resource.unconfirmed_email%>< / div>
<%end%>

< div>
<%= f.label:password%>< br />
<%= f.password_field:password%>
< / div>

< div>
<%= f.label:password_confirmation%>< br />
<%= f.password_field:password_confirmation%>
< / div>

< div>
<%= f.label:current_password%> < i(我们需要您当前的密码来确认您的更改)< / i>< br />
<%= f.password_field:current_password%>
< / div>


解决方案

通过网站搜索后,我已经找到了如何以便让这个工作。



我的第一个业务是使用这个 devise wiki

  def update 
#对于Rails 4
account_update_params = devise_parameter_sanitizer.sanitize(:account_update)
#对于Rails 3
#account_update_params = params [:user]

#当密码留空时,设置表单提交时需要#
如果account_update_params [:password] .blank?
account_update_params.delete(password)
account_update_params.delete(password_confirmation)
end

@user = User.find(current_user.id)
如果@ user.update_attributes(account_update_params)
set_flash_message:通知,更新
#登录用户绕过验证,以防其密码更改
sign_in @user,:bypass => true
redirect_to after_update_path_for(@user)
else
呈现edit
end
end

接下来,正在添加一个方法来替代上述代码上方的用户当前密码的验证。特别感谢Lauri Laine在这篇文章中的答案:使用Devise和Omniauth编辑用户

 #覆盖update_resource,让用户在不给出密码的情况下更新用户
def update_resource(资源,参数)
如果current_user.provider ==facebook
params.delete(current_password)
resource.update_without_password(params)
else
resource.update_with_password(params )
end
end

最后我不得不添加:current_password 作为我的用户模型的虚拟属性,一切正常!

  attr_accessor:current_password 

希望这有助于任何有/将遇到此问题的人。我知道这让我很痛快,但很高兴能够把它全部弄清楚。将会与omniauth的twitter宝石一起测试。


Using Devise with Omniauth I was successfully able to allow users to login with their Facebook accounts. With the help of the Omniauth wiki I was also able to disable having to put in a password when editing their account.

The current problem I'm faced with is hiding the password fields in my registrations#edit view if they signed up via Facebook. As a newcomer to both gems I'm still trying to adjust. So when it comes to setting up the necessary helper method(s) I'm sort've at a loss.

As instructed by the wiki here's what my Registrations controller looks like:

class RegistrationsController < Devise::RegistrationsController
  before_filter :configure_permitted_parameters, if: :devise_controller?

  def update
    @user = User.find(current_user.id)

    successfully_updated = if needs_password?(@user, params)
      @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
    else
      # remove the virtual current_password attribute
      # update_without_password doesn't know how to ignore it
      params[:user].delete(:current_password)
      @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
    end

    if successfully_updated
      set_flash_message :notice, :updated
      # Sign in the user bypassing validation in case their password changed
      sign_in @user, :bypass => true
      redirect_to after_update_path_for(@user)
    else
      render "edit"
    end
  end

  private

  # check if we need password to update user data
  # ie if password or email was changed
  # extend this as needed
  def needs_password?(user, params)
    user.email != params[:user][:email] ||
      params[:user][:password].present? ||
      params[:user][:password_confirmation].present?
  end

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) do |u|
      u.permit(:first_name, :last_name, :email, :password, :password_confirmation)
    end
    devise_parameter_sanitizer.for(:account_update) do |u|
      u.permit(:first_name, :last_name, :email, :password, :password_confirmation)
    end
  end
end

And here is my registrations#edit view:

<% provide :title, 'Edit Profile' %>

<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
  <%= devise_error_messages! %>

  <div><%= f.label :first_name %><br />
  <%= f.text_field :first_name %></div>

  <div><%= f.label :last_name %><br />
  <%= f.text_field :last_name %></div>

  <div><%= f.label :email %><br />
  <%= f.email_field :email %></div>

  <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
    <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
  <% end %>

  <div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
    <%= f.password_field :password, autocomplete: "off" %></div>

  <div><%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "off" %></div>

  <div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
    <%= f.password_field :current_password, autocomplete: "off" %></div>

  <div><%= f.submit "Update" %></div>
<% end %>

UPDATE

After some extensive research I was able to find a question that inderictly answered what I was looking for in terms of hiding the input fields (second to last comment in the question). The only problem is that for some reason it triggers a password validation error despite it not being there...

   <div>
    <%= f.label :first_name %><br />
    <%= f.text_field :first_name %>
  </div>

  <div>
    <%= f.label :last_name %><br />
    <%= f.text_field :last_name %>
  </div>

  <% if user_signed_in? && !current_user.provider == 'facebook' %>
    <div>
      <%= f.label :email %><br />
      <%= f.email_field :email %>
    </div>

    <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
      <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
    <% end %>

    <div>
      <%= f.label :password %><br />
      <%= f.password_field :password %>
    </div>

    <div>
      <%= f.label :password_confirmation %><br />
      <%= f.password_field :password_confirmation %>
    </div>

    <div>
      <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
      <%= f.password_field :current_password %>
    </div>

解决方案

After searching through the site I have FINALLY found out how to get this to work.

My first order of business was to to use the first code example for the registrations controller from this devise wiki

  def update
    # For Rails 4
    account_update_params = devise_parameter_sanitizer.sanitize(:account_update)
    # For Rails 3
    # account_update_params = params[:user]

    # required for settings form to submit when password is left blank
    if account_update_params[:password].blank?
      account_update_params.delete("password")
      account_update_params.delete("password_confirmation")
    end

    @user = User.find(current_user.id)
    if @user.update_attributes(account_update_params)
      set_flash_message :notice, :updated
      # Sign in the user bypassing validation in case their password changed
      sign_in @user, :bypass => true
      redirect_to after_update_path_for(@user)
    else
      render "edit"
    end
  end

Next was adding a method to override the validation for the user's current password just above the code above. Special thanks to Lauri Laine for her answer in this post: Editing Users With Devise and Omniauth

  # 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

Lastly I had to add :current_password as a virtual attribute to my user model and everything worked!

attr_accessor :current_password

Hopefully this helps anyone who has/will encounter this problem. I know it had me stumped for a minute but glad I was able to figure it all out. Will be testing this soon in conjunction with omniauth's twitter gem.

这篇关于Devise - Omniauth - 如果用户通过Facebook登录,隐藏密码字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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