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
相关产品推荐
相关产品推荐

