비밀번호없이 업데이트 사용자 고안
비밀번호없이 사용자 속성을 업데이트하고 싶습니다. 이 경우는 암호 및 암호 확인 필드가 비어 있지 않으면 고안 오류가 필요하고 비어 있으면 다른 사용자 속성을 업데이트해야합니다. devise로 어떻게 할 수 있습니까?
미리 감사드립니다!
이것이 당신이 찾는 것입니까? Devise 위키에서
사용자가 비밀번호를 제공하지 않고 계정을 편집 할 수 있도록 허용
레일 3 및 레일 4에 대해 수행하는 방법을 보여줍니다.
=======================
John의 솔루션 은 더 간단한 대안입니다.
나는 이것이 훨씬 더 나은 해결책이라고 생각합니다.
if params[:user][:password].blank? && params[:user][:password_confirmation].blank?
params[:user].delete(:password)
params[:user].delete(:password_confirmation)
end
이렇게하면 양식 응답이 비어있는 경우 단순히 암호 필드를 제거하여 Devise 컨트롤러를 변경할 필요가 없습니다.
그냥이를 사용해야 하기 전에 @user.attributes = params[:user]
또는 무엇 이건 당신은 당신의에서 사용하는 update
양식에서 새로운 매개 변수를 설정하는 액션입니다.
Devise 3.2 이상에서는 하위 클래스 컨트롤러에서 update_resource를 재정의 할 수 있다고 생각합니다. 다음은 원래 질문에 대한 예입니다.
class MyRegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
end
이 문제를 다음과 같이 해결했습니다. 양식을 비밀번호로 제출하는 경우 current_password 필드를 채우거나 비밀번호와 current_password없이 업데이트 된 양식이 필요합니다.
모델 :
class User
devise: bla-bla-bla
attr_accessor :current_password
end
컨트롤러에서 :
class Users::RegistrationsController < Devise::RegistrationsController
layout 'application'
def update
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
# custom logic
if params[:user][:password].present?
result = resource.update_with_password(params[resource_name])
else
result = resource.update_without_password(params[resource_name])
end
# standart devise behaviour
if result
if is_navigational_format?
if resource.respond_to?(:pending_reconfirmation?) && resource.pending_reconfirmation?
flash_key = :update_needs_confirmation
end
set_flash_message :notice, flash_key || :updated
end
sign_in resource_name, resource, :bypass => true
respond_with resource, :location => after_update_path_for(resource)
else
clean_up_passwords resource
respond_with resource
end
end
end
내 인터페이스로이 문제를 해결합니다. 두 가지 방법이 있습니다.
필드가 비어있는 경우 비활성화
이 jQuery 비트는 비어있는 경우 양식이 제출되기 전에 필드를 비활성화합니다. 특정 마크 업 패턴이 필요합니다 . Codepen 의 데모를 확인하십시오 .
$(".password-fields").each(function() {
var $fields, $form;
$form = $(this).parents("form");
$fields = $(this).find("input");
$form.on("submit", function() {
$fields.each(function() {
if ($(this).val() === "") {
$(this).attr("disabled", "disabled");
}
});
});
});
사용자에게 업데이트를 원하는지 선택할 수있는 확인란을 제공합니다.
또 다른 옵션은 사용자가 암호 업데이트를 원한다고 표시하지 않은 경우 양식에서 암호 필드를 제거하는 것입니다. 다음 은 CodePen 의 예 입니다 .
$(".password-fields").each(function () {
var $fields, $button, html;
$fields = $(this);
$button = $fields.prev(".update-password").find("input");
html = $fields.html();
$button
.on("change", function () {
if ( $(this).is(":checked") ) {
$fields.html(html);
}
else {
$fields.html("");
}
})
.prop("checked", "checked")
.click();
});
두 경우 모두 앱 자체에 대한 업데이트가 필요하지 않습니다. 변경하려는 필드를 제출하는 것입니다.
대신 #password_required를 재정의합니까? 사용자 모델 내부의 메소드.
class User < ActiveRecord::Base
devise :database_authenticatable, :validatable #, ...
def password_required?
if respond_to?(:reset_password_token)
return true if reset_password_token.present?
end
return true if new_record?
password.present? || password_confirmation.present?
end
end
따라서 사용자가 새로운 경우 그는 암호를 지정해야합니다. 그러나 존재하는 사용자는 password 또는 password_confirmation 속성을 입력하는 경우에만 암호를 지정해야합니다.
자세한 내용은 https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L33을 참조하십시오.
내 구현은 원본과 거의 동일합니다 : https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L53
내가 존재하는지 확인하는 것을 제외하고 (빈 문자열에 대해 false를 반환)
이 문제에 대한 내 풀 요청에 대한 토론은 다음과 같습니다. https://github.com/plataformatec/devise/pull/3920
여전히 암호 변경을 지원하고 싶지만 선택 사항으로 설정하려면 다음 current_password
과 같은 가용성을 확인하십시오 .
class MyRegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
if params[:current_password].blank?
resource.update_without_password(params.except(:current_password))
else
resource.update_with_password(params)
end
end
end
이렇게하면 current_password가있는 경우 계속해서 암호를 업데이트 할 수 있습니다. 그렇지 않으면 무시하고 암호없이 업데이트 할 수 있습니다.
사용자가 비밀번호를 변경하려고 할 때만 Devise가 현재 비밀번호를 확인 하도록하려면 ( 즉, 현재 비밀번호를 제공하지 않고도 다른 속성을 변경할 수 있음 ) :
class RegistrationsController < Devise::RegistrationsController
protected
def update_resource(resource, params)
if params[:password].blank? && params[:password_confirmation].blank?
resource.update_without_password(params)
else
super
end
end
end
또한 모델에서 :
attr_accessor :current_password
그리고 잊지 마세요
devise_for :users, controllers: {registrations: 'registrations'}
에 routes.rb .
사용자 모델에있는 해결 방법
def password_required?
encrypted_password.blank? || encrypted_password_changed?
end
params [: user] [: password]가 rails 6에서 작동하지 않습니다.
params [: user] [: password] 를 params [: password] 로 변경해야 합니다.
모든 매개 변수에서 [: user] 제거
내 소스 코드는 다음과 같습니다.
이 명령을 실행하기 전에
rails는 devise를 생성합니다 : controllers users -c = registrations
class Users::RegistrationsController < Devise::RegistrationsController
# before_action :configure_sign_up_params, only: [:create]
# before_action :configure_account_update_params, only: [:update]
protected
def update_resource(resource, params)
puts "params ===> #{params}"
if params[:password].blank? && params[:password_confirmation].blank?
params.delete(:password)
params.delete(:password_confirmation)
params.delete(:current_password)
resource.update_without_password(params)
else
super
end
end
end
더 많은 비즈니스 로직이므로 컨트롤러에 너무 많은 코드를 넣지 않을 것입니다. Devise::Models::Validatable#password_required?
모델에서 재정의 하는 것이 좋습니다 .
def password_required?
new_record? || password.present? || password_confirmation.present?
end
나는 똑같은 문제가 있었고 이것이 내가 생각해 낸 해결책이며 작동한다고 믿습니다. 내가 한 일은 두 번째 user_params
방법을 만들고 이름을 지정 user_params_no_pass
하는 것입니다. 여기서 일어나는 일은 암호를 업데이트해야 할 때 관리자가 암호를 제공하고 그렇지 않으면 암호를 비워 두는 것입니다. 암호가 비어 있으면 user_params_no_pass
다른 이름이 사용됩니다 user_params
. 도움이 되길 바랍니다
def update
if @user.valid_password?(params[:user][:password])
respond_to do |format|
if @user.update(user_params)
format.html { redirect_to @user, notice: 'User profile was successfully updated.' }
format.json { render :show, status: :ok, location: @user }
else
format.html { render :new }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
else
respond_to do |format|
if @user.update(user_params_no_pass)
format.html { redirect_to @user, notice: 'User profile was successfully updated without password.' }
format.json { render :show, status: :ok, location: @user }
else
format.html { render :edit }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
end
def destroy
@user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_user
@user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:user_name, :first_name, :middle_name, :last_name, :dob, :gender, :race, :hispanic, :leader, :mentor, :student, :email, :organization_id, :password, :opus,
:release_date, :days_to_release, :current_level, :is_active)
end
def user_params_no_pass
params.require(:user).permit(:user_name, :first_name, :middle_name, :last_name, :dob, :gender, :race, :hispanic, :leader, :mentor, :student, :email, :organization_id, :opus,
:release_date, :days_to_release, :current_level, :is_active)
end
I find this slight variation on the code above easier to follow:
def update
@user = User.find(params[:id])
method = if user_params[:password].blank?
:update_without_password
else
:update_with_password
if @user.send(method, user_params)
redirect_to @user, notice: 'User settings were saved.'
else
render :edit
end
end
After much exploration of the above possibilities I finally found a solution which allows you to update some attributes without a password and some with:
I made a view for user/edit.html.erb with the following form in it.
<%= form_for(@user) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.submit "Save changes"%>
<% end %>
I set routes in routes.rb
resources :users, only: [:show, :index, :edit, :update]
I made edit and update methods in users_controller.rb
def edit
@user = current_user
end
def update
@user = current_user
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to root_url
else
render 'edit'
end
end
def user_params
params.require(:user).permit(:name, :avatar, :whatsup)
end
I used this edit view for changes which did not require a password. It skips the devise registration controller entirely because I link to it with
edit_user_path(current_user)
I also set the params so that email and password cannot be changed here. To update password and email, I link to the stock generated devise view:
edit_user_registration_path(current_user)
I admit that this is a huge work around but none of the simpler solutions solved all of the above problems.
Better and short way: add check params into the user_params block. For example:
def user_params
up = params.require(:user).permit(
%i[first_name last_name role_id email encrypted_password
reset_password_token reset_password_sent_at remember_created_at
password password_confirmation]
)
if up[:password].blank? && up[:password_confirmation].blank?
up.delete(:password)
up.delete(:password_confirmation)
end
up
end
to update attributes for user, you will need to use :current_password, to check 'do your user use correct current_password or someone wants to break your user'
so in form:
= f.input :current_password,
hint: "we need your current password to confirm your changes",
required: true,
input_html: { autocomplete: "current-password" }
in controller:
if your_user.valid_password?(params[:user][:current_password])
your_user.update_attributes(user_params.except(:current_password, :password, :password_confirmation))
end
the first line checks 'do your user sends the correct password or not', and then we can to update the attributes without garbage
참고URL : https://stackoverflow.com/questions/5113248/devise-update-user-without-password
'program story' 카테고리의 다른 글
Rails 4 기본 범위 (0) | 2020.10.23 |
---|---|
IntelliJ / Android Studio의 한 파일에 대한 잘못된 파일 연결 (0) | 2020.10.23 |
모든 '키 : 값'에 대해 한 줄씩 csv 파일에 사전 쓰기 (0) | 2020.10.23 |
IE9-10에서 SVG를 사용한 배경 크기 (0) | 2020.10.23 |
피쉬 쉘에서 환경 변수를 설정하는 방법 (0) | 2020.10.23 |