Как обновить пароль пользователя с помощью password_digest и формы в Rails - PullRequest
0 голосов
/ 01 марта 2020

У меня есть файлы ниже, чтобы обновить детали пользователя. в настоящее время они работают для всего, кроме пароля. все логики c работают правильно, я использовал puts, чтобы проверить, что введены правильные разделы логики c, однако кажется, что пароль никогда не обновляется в конце при вызове @user.update(user_params).

Чтобы заставить это работать, я должен добавить две строки ниже в logi c пароля в UserController, что не кажется логичным, учитывая, что я вызываю @user.update(user_params), что должно обновить пользователя с пользователем параметры предоставлены. Буду очень признателен за любые советы, предложения или комментарии.

@user.password = params[:user][:password]
@user.save

Я не использую какие-либо Gems et c для аутентификации, и моя таблица пользователей выглядит следующим образом

create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "password_digest"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "title"
    t.string "firstName"
    t.string "surname"
    t.index ["username"], name: "index_users_on_username", unique: true
end

UserController

class UsersController < ApplicationController

  skip_before_action :authorized, only: [:new, :create]
  before_action :set_user, only: [:update]
  def new
    @user = User.new
  end

  def create
    @user = User.create(params.require(:user).permit(:username, :password))
    session[:user_id] = @user.id
    redirect_to '/welcome'
  end

  def update
    errorMessage = ''
    if current_user.username != params[:user][:username]
      if User.find_by(username: params[:user][:username]).nil?
      else
        errorMessage += "Username is already taken"
      end
    else
    end
    if !params[:user][:password].blank?
      if @user.authenticate(params[:user][:password_confirmation])
      else
        errorMessage += "Confirmation password is incorrect"
      end
    else
    end

    if !errorMessage.blank?
      redirect_to account_path, notice: errorMessage
    else
      @user.update(user_params)
      redirect_to account_path
    end
  end

  private 
  def user_params
    params.require(:user).permit(:username, :title, :firstName, :surname,:password, :password_confirmation)
  end
  def set_user
    @user = current_user
  end
end

edit. html .erb

<p id=”notice”><%= notice %></p>
<%= form_for current_user do |f|%>
    <div class="form-group row col-md-12">
        <%= f.label :username, class:"col-sm-2 col-form-label"%><br>
        <%= f.text_field :username, class:"form-control col-sm-10" %>
    </div>

    <div class="form-group row col-md-12">
        <div class="col-md-2">
            <%= f.label :title%><br>
            <%= f.text_field :title, class:"form-control" %>
        </div>
        <div class="col-md-5">
            <%= f.label :firstName, "First Name" %><br>
            <%= f.text_field :firstName, class:"form-control" %>
        </div>
        <div class="col-md-5">
            <%= f.label :surname %><br>
            <%= f.text_field :surname, class:"form-control" %>
        </div>
    </div>

    <div class="form-group row col-md-12">
        <div class="col-md-6">
            <%= f.label :password_confirmation, "Current Password"%><br>
            <%= f.password_field :password_confirmation, class:"form-control" %>
        </div>
        <div class="col-md-6">
            <%= f.label :password, "New Password"%><br>
            <%= f.password_field :password, class:"form-control" %>
        </div>
        <small id="passwordHelpBlock" class="form-text text-muted col-md-12">
            To update your password, please confirm your current password.
        </small>
    </div>

    <%= f.submit "Submit" ,class: "btn btn-primary"%>
<% end %>

Модель пользователя

class User < ApplicationRecord
    has_secure_password
end

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Ваш контроллер немного сложен, я предполагаю, что это как-то вызывает вашу проблему. Вы должны вывести ошибки в представлении, чтобы увидеть, что происходит не так, к сожалению, это не было частью вашего вопроса. Тем не менее, в общем случае есть два варианта , чтобы описать эту работу в bcrypt ruby Github репозитории . Обратите внимание, я не пробовал с current_user, params[:user] и @user.authenticate удалить сложность и сконцентрироваться на bcrypt topi c.

Опция 1

Использование has_secure_password в вашей пользовательской модели, например:

class User < ApplicationRecord
  has_secure_password
end

Вам нужен столбец дайджеста пароля и вам нужно работать с :password в ваш метод user_params.

def user_params
  params.require(:user).permit(:username, :title, :firstName, :surname, :password, :password_confirmation)
end

Введенный пароль будет сохранен в базе данных в столбце password_digest.

Опция 2

Это описано для пользовательская модель страницы bcrypt Github .

В этом случае вы НЕ используете has_secure_password, но добавляете следующий код в вашу модель пользователя:

class User < ApplicationRecord
  include BCrypt

  def password
    @password ||= Password.new(password_hash)
  end

  def password=(new_password)
    @password = Password.create(new_password)
    self.password_hash = @password
  end
end

Тогда ваш user_params метод должен отражать имя атрибута :password_hash:

def user_params
  params.require(:user).permit(:username, :title, :firstName, :surname, :password_hash, :password_confirmation)
end

В этом случае вашей базе данных потребуется столбец password_hash вместо password_digest, чтобы он работал, используя Пример кода выше. Конечно, вы также можете повторно использовать password_digest вместо password_hash, а затем заменить password_hash в приведенном выше коде на password_digest.

Примечания

В обоих случаях я использую вид, который вы сделали с полем password:

<div class="form-group row col-md-12">
  <div class="col-md-6">
    <%= f.label :password, "New Password"%><br>
      <%= f.password_field :password, class:"form-control" %>
  </div>
</div>

Контроллер в моих тестах выглядел так:

def update
  if @user.update(user_params)
    redirect_to @user, notice: 'User was successfully updated.'
  else
    render :edit
  end
end

Тестовое приложение

У меня также есть добавили это небольшое тестовое приложение с помощью опции 1 с has_secure_password в репозиторий Github @ https://github.com/cadamini/rails-bcrypt-ruby-test

1 голос
/ 02 марта 2020

Откройте app/models/user.rb и добавьте метод has_secure_password в свой класс User. has_secure_password и password_digest работают вместе в bcrypt, поэтому оба должны присутствовать для его работы.

...