哈希密码未保存在密码列中

时间:2016-04-13 08:50:21

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

我正在尝试在注册时在我的def login @title = 'Login' #render layout: 'login' end def create_login user = User.authenticate(params[:user][:username], params[:user][:password]) if user log_in user redirect_to '/admin' else flash[:danger] = 'Invalid email/password combination' # Not quite right! redirect_to :back end end def register @user = User.new @title = 'Register' end def create_register params[:user][:uniq_id] = generate_uniq @user = User.new(create_user_params) #raise @user.inspect respond_to do |format| if @user.save format.html { redirect_to :success, success: 'Registration was successfully created.' } format.json { redirect_to :register, status: :created, location: @users } else format.html { render :register } format.json { render json: @users.errors, status: :unprocessable_entity } end end end private def create_user_params params.require(:user).permit(:uniq_id, :name, :username, :email, :password, :password_confirmation, :password_salt, :dob, :address) end 表中存储哈希密码。请看我的代码:

users_controller.rb

<%= form_tag("/register", method: "post") do %>
        <%#= form_tag(@user) do |f| %>
         <% if @user.errors.any? %>
          <div id="error_explanation">
            <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
            <ul>
              <% @user.errors.full_messages.each do |message| %>
                <li><%= message %></li>
              <% end %>
            </ul>
          </div>
        <% end %>


          <%= text_field :user, :name, placeholder:'NAME', required: true %>
          <div style="position: relative;">
            <span id="chk-username" style="position: absolute;font-size: 12px;right: 2%; bottom: 5%; z-index: 9; display: block;"></span>
            <%= text_field :user, :username, placeholder:'USERNAME', 'data-validate':"/users/check_username", required: true %>
          </div>
          <div style="position: relative;">
            <span id="chk-email" style="position: absolute;font-size: 12px;right: 2%; bottom: 5%; z-index: 9; display: block;"></span>
            <%= text_field :user, :email, placeholder:'EMAIL', 'data-validate':"/users/check_email", required: true %>
          </div>
          <%= password_field :user, :password, placeholder:'PASSWORD', required: true %>  
          <%= password_field :user, :password_confirmation, placeholder:'CONFIRM PASSWORD', required: true %> 
          <div class="submit">
            <input type="submit" value="REGISTER" >
            <input type="button" onclick="location.href = '<%= request.base_url %>/login'" value="LOGIN" >
          </div>    
          <p><a href="#">Forgot Password ?</a></p>
<% end %>

register.html.erb

class User < ActiveRecord::Base
  #has_secure_password

  attr_accessor :password
  before_save :encrypt_password

  validates :name, presence: true


  validates :name, length: { minumum:2, maximum: 30 }

  validates :password, :presence =>true,
    :length => { :minimum => 6, :maximum => 40 },
    :confirmation =>true

  validates :username, :presence => true,
    :uniqueness => { :case_sensitive => false }

  email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, :presence => true,
    :format => { :with => email_regex },
    :uniqueness => { :case_sensitive => false }


  def self.authenticate(input_username, input_password)
    user = find_by_username(input_username)
    if user && user.password == BCrypt::Engine.hash_secret(input_password, user.password_salt)
      user
    else
      nil
    end
  end

  def encrypt_password
    if password.present?
      self.password_salt = BCrypt::Engine.generate_salt
      self.password = BCrypt::Engine.hash_secret(password, password_salt)
    end
  end
end

user.rb

get    'register'   => 'users#register'
post   'register'   => 'users#create_register'

的routes.rb

+----+----------+------------+-----------+----------------+
| id | name     | username   |  password |  password_salt |
+----+----------+------------+-----------+----------------+
|  1 | chinmay  | chinu      | NULL      |$2a$10$15fWDt.. |
|  2 | sanjib   | sanjib     | NULL      |$2a$10$85DyMr.. |
+----+----------+------------+-----------+----------------+

这是我的数据库表。

users.sql(自定义表格)

NULL

我在password列中获得Dim rng As Range Set rng = Range("D15") With Sheet1 .Shapes("Group 9").Left = rng.Left - (.Shapes("Group 9").Width / 2) + (rng.Width / 2) .Shapes("Group 9").Top = rng.Top - (.Shapes("Group 9").Height / 2) + (rng.Height / 2) End With 值。请帮助我,让我知道我的代码中的错误。

1 个答案:

答案 0 :(得分:1)

您的主要错误是您使用attr_accessor :password为密码属性创建getter / setter,该属性覆盖ActiveRecord从数据库架构创建的getter和setter。

但是,您对密码加密的整个方法存在缺陷 - 您应该password纯粹为virtual attribute,并将数据库列命名为password_digestencrypted_password

除非出于纯粹的学习目的,否则应使用Rails提供的has_secure_password宏,而不是重新发明密码加密轮并被黑客攻击。

1。向用户添加password_digest列:

rails g migration AddPassWordDigestToUser password_digest:string:index

您可能希望删除password_salt列以及ActiveModel::SecurePassword未使用该列。

class AddPassWordDigestToUser < ActiveRecord::Migration
  def change
    add_column :users, :password_digest, :string
    add_index :users, :password_digest
    remove_column :users, :password_salt
    remove_column :users, :password
  end
end

2。将has_secure_password添加到用户模型:

class User < ActiveRecord::Base
  has_secure_password
end

3。 RESTful路线

您可能想要更正路由,使它们面向资源而不是面向操作,并遵循rails约定:

GET  /registrations/new   registations#new     - sign up form
POST /registrations       registations#create  - create user

GET  /sessions/new        sessions#new         - sign in form
POST /sessions            sessions#create      - sign in user

您可以使用以下方式设置路线:

resources :registrations, only: [:new, :create]
resources :sessions, only: [:new, :create]

请参阅Rails Routing from the Outside In

4。绑定表单和控制器。

您正在正确设置控制器,但您的表单未绑定到您在控制器中创建的@user模型实例。

这意味着在表单提交失败后,用户输入的值将消失。

还要注意变量的复数和命名!您不一致地使用@user@users。在这种情况下,@users将始终为零并导致错误。

应用程序/控制器/ registrations_controller.rb:

class RegistationsController < ApplicationController

  def new
    @user = User.new
  end

  def create
    # Use a block instead of messing with the incoming params.
    @user = User.new(user_params) do |u|
      u.uniq_id = generate_uniq
    end 

    if @user.save
      respond_to do |format|
        format.html { redirect_to root_path, success: "Welcome #{@user.email}" }
        format.json { status: :created, location: @user } 
      end
    else
      respond_to do |format|
        format.html { redirect_to :new }
        format.json { render json: @user.errors, status: :unprocessable_entity } 
      end
    end
  end

  private

    def user_params
      params.require(:user).permit(:email, :password, :password_confirmation)
    end

end

应用程序/视图/注册/ new.html.erb:

<%= form_for(@user, url: registrations_path) do |f| %>
  <div class="row">
    <%= f.label :email %>
    <%= f.text_field :email %>
  </div>
  <div class="row">
    <%= f.label :password %>
    <%= f.password_field :password %>
  </div>
  <div class="row">
    <%= f.label :password_confirmation %>
    <%= f.password_field :password_confirmation %>
  </div>
<% end %>