设计:仅在某些情况下询问密码

时间:2013-04-07 20:04:01

标签: ruby-on-rails ruby-on-rails-3 devise

我正在使用Rails和Devise开发一个应用程序来进行用户身份验证。我想知道是否有办法只在一些变化时询问密码。

例如,我想在以下时间询问密码:

  • 删除帐户
  • 更改密码

我希望用户可以在没有任何密码的情况下自由编辑其他字段,例如:

  • 名称
  • 用户名
  • 头像

所以,我想要一种在这两种方法之间进行交换的方法。我该如何解决这个问题?

编辑:

在Devise的文档中我发现了这个并且它工作正常,它只允许在我输入密码时更改密码和电子邮件:

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

    successfully_updated = if needs_password?(@user, params)
        @user.update_with_password(params[:user])
    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(params[:user])
    end

    if successfully_updated
        set_flash_message :notice, :updated
         # Sign in the user bypassing validation in case his 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].blank?
    #HERE
end

现在,当我删除帐户时,我可以在#HERE添加什么密码?

3 个答案:

答案 0 :(得分:3)

由于问题编辑:

def destroy
  if current_user.valid_password?(params[:user][:password])
    current_user.destroy
  else 
    render "destroy" # or what ever
  end
end

答案 1 :(得分:0)

您可以创建form_tag重定向到控制器中的操作。

<%= form_tag url_for(:controller => :users, :action => :destroy), :method => :get do %>
  <%= label_tag(:password, "Enter password before deleting") %>
  <%= password_field_tag :password %>
  <%= submit_tag "Delete User With Confirmation" %>
<% end %>

您的UsersController中的操作类似于:

def destroy
    if current_user.authenticate(params[:password])
         #do something
    else
         #do something
    end
end

答案 2 :(得分:0)

Devise中有一个destroy_with_password方法(至少从版本3.5.2开始)。它在lib/devise/models/database_authenticatable.rb中,由

调用
destroy_with_password(current_password)

如果current_password匹配则会销毁记录,否则返回false。