我有一个使用bcrypt gem的登录表单。它在rails控制台中按预期工作。但是,我在网站上收到这些错误。非常感激任何的帮助。
ManagersController#login中的NoMethodError尝试将未定义的方法“验证”为true:TrueClass
我已经阅读了几篇SO帖子-我使用过一些修正,但无法解决错误:
例如-这是因为authenticate类没有前缀“ self”,所以该建议实际上破坏了终端@some_user.authenticate('***********') => true
的工作功能
def authenticate(password)
self.password_hash == BCrypt::Engine.hash_secret(password, password_salt)
end
or
def self.authenticate(password)
self.password_hash == BCrypt::Engine.hash_secret(password, password_salt)
end
or
def self.authenticate(password)
password_hash == BCrypt::Engine.hash_secret(password, password_salt)
end
型号
class Manager < ApplicationRecord
attr_accessor :password
validates :username, presence: true, uniqueness: true
validates :password, presence: true, on: :create
before_validation(on: :create) do
encrypt_password
end
def authenticate(password)
password_hash == BCrypt::Engine.hash_secret(password, password_salt)
end
private
def encrypt_password
self.password_salt = BCrypt::Engine.generate_salt
self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
end
end
控制器-会产生错误。
class ManagersController < ApplicationController
...
def loginattempt
@manager = Manager.where(manager_params).exists?
if @manager && @manager.authenticate(manager_params)
redirect_to managers_path, notice: 'You are logged in.'
else
redirect_to manager_login_path, notice: 'Username or Password incorrect.'
end
end
private
def manager_params
params.require(:manager).permit(:username, :password)
end
end
为后代 我相信它现在可以按预期运行了-感谢SO社区在我需要帮助的时候为我提供帮助。 工作控制器
def loginattempt
@manager = Manager.find_by_username(manager_params[:username])
if @manager.present? && @manager.authenticate(manager_params[:password])
redirect_to manager_logged_in_path(@manager), notice: 'Logged In.'
session[:logged_in] = @manager.id
else
redirect_to manager_login_path, notice: 'Username or Password incorrect.'
end
end
答案 0 :(得分:1)
一些注意事项:
Manager.where(manager_params)
是多余的,因为manager_params
类似于{manager: {username: 'foo', password: 'password'}}
,但是where
方法采用像{username: 'foo', password: 'password'}
这样的简单哈希。find_by
而不是where
和exists?
,因为exists?
返回布尔值,这不是您想要的。如果记录不存在,find_by
返回nil。Manager#authenticate
方法(authenticate
类的Manager
实例方法)仅需要密码,因此您可以使用@manager.authenticate(params[:manager][:password])
代替@manager.authenticate(manager_params)
我想提到的是,如果username
是唯一的,我们只能通过username
来找到用户,而无需输入密码。