You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails登录时SessionsController出现BCrypt无效哈希错误如何解决?

Rails登录功能BCrypt无效哈希报错排查

错误信息

BCrypt::Errors::InvalidHash in SessionsController#create
invalid hash

请求参数

{"authenticity_token"=>"[FILTERED]", "email"=>[""], "session_password"=>"[FILTERED]", "commit"=>"Log in"}

相关代码

1. 会话控制器(SessionsController)

class SessionsController < ApplicationController
  def new
  end

  def create
    user = User.find_by_email(params[:email])
    if user && user.authenticate(params[:password]) #error line 

      session[:user_id] = user.id
      redirect_to 'posts/index'
    else
      flash.now[:alert] = 'Invalid email or password'
      render 'new'
    end
  end

  def destroy
    session[:user_id] = nil
    redirect_to '/login'
  end
end

2. 用户控制器(UsersController)

class UsersController < ApplicationController
  before_action :authorized, only: [:show]
  def new
    @user = User.new
  end

  def index
  end

  def show
    @user = User.find(params[:id])
  end

  def create
    @user = User.new(user_params)
    @user.password = params[:password]
    if @user.save
      session[:user_id] = user.id
      redirect_to root_path
    else
      render :new
    end
  end

  private
  def user_params
    params.
      permit(:name, :email, :password, :password_confirmation)
  end
end

3. 注册表单代码

<%= stylesheet_link_tag "signup.css" %>

<%= form_with(model: user) do |f| %>
  <div class="field">
    <%= f.text_field :name,placeholder:"Full Name", class: 'signup-textfield'%>
  </div>
  <div class="field">

    <%= f.email_field :email, placeholder: "Email", class: 'signup-textfield' %>
  </div>
  <div class="field">
    <%= f.password_field :password,placeholder:'Password', class: 'signup-textfield' %>
  </div>
  <div class="field">
    <%= f.password_field :password_confirmation,placeholder: 'Confirm password', class: 'signup-textfield' %>
  </div>
  <div class = "field">

    <p>Investor</p>
    <%= f.radio_button :type, 'Investor',class:'radiobutton' %>
    <p>Investee</p>
    <%= f.radio_button :type, 'Investee', class:'radiobutton'%>

  </div>
  <div class="actions">
    <%= f.submit id: "signup-button" %>
  </div>

<% end %>

修复方案
  • 参数键不匹配问题:请求参数中密码字段的键是session_password,但会话控制器中调用authenticate方法时取的是params[:password],导致实际传入空值触发哈希校验错误。可以选择将user.authenticate(params[:password])改为user.authenticate(params[:session_password]),或者直接修改登录表单的密码字段name属性为password。
  • email参数格式错误:请求参数中email为数组类型[""],说明登录表单的email字段配置错误,启用了数组提交格式。优先检查修改登录表单的email字段,确保其name属性为email而非email[],临时兼容可以将用户查询逻辑改为User.find_by(email: params[:email].first)。
  • 用户控制器错误修复:用户控制器的create方法中,已经通过user_params传入了密码参数,不需要额外赋值@user.password = params[:password];同时保存成功后赋值session时调用的user.id未定义,需要改为@user.id。
  • 若修改后仍然报错,可额外检查User模型是否正确添加了has_secure_password声明,同时确认数据库password_digest字段长度不小于60字符。

内容的提问来源于stack exchange,提问作者Isabel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 23:06:07