我正在尝试使用BCrypt构建一个使用用户名和密码身份验证的非常简单的登录页面。
有两个功能,第一个是创建用户名和密码,第二个是使用登录页面进行身份验证。 (创建新用户,使用该用户登录)
以下是用于创建用户名和密码的控制器和用户型号代码。视图模型不包括在内,但它包含一个简单的表单,要求用户创建用户名,密码和确认密码
控制器:
get '/new_user' do
erb :new_user
end
post '/new_user' do
if @password == @password_confirm
new_user = User.new(username: params[:username])
new_user.password = params[:password]
new_user.insert_user
redirect '/index'
else
redirect '/new_user'
end
end
型号:
def initialize(params = {})
@username = params.fetch(:username, "test")
@password = params.fetch(:password, "test")
end
def password=(new_password)
@password = BCrypt::Password.create(new_password)
@db_password = BCrypt::Password.new(@password)
end
def insert_user
db = SQLite3::Database.open("helper_database")
db_results_as_hash = true
db.execute("INSERT INTO users (username, password) VALUES (?,?)", [@username, @db_password])
end
在上面,创建了一个新实例来传递用户名和密码。如果密码和确认密码匹配,密码方法将创建加密密码,insert方法将使用简单的SQL命令将用户名和加密密码插入数据库。
将用户名和加密密码插入数据库后。我想使用登录页面进行验证。我创建一个新的User实例,将用户名和密码params传递给下面显示的身份验证方法。该方法将查找与params用户名对应的密码,并根据加密密码评估params密码。
以下是登录的控制器和用户模型
控制器:
get '/login' do
erb :login
end
post '/login' do
@user = User.new(username: params[:username], password: params[:password])
if @user.authenticate()
redirect '/index'
else
erb :login
end
end
型号:
def authenticate
db = SQLite3::Database.open("helper_database")
db.results_as_hash = true
password = db.execute("SELECT password FROM users WHERE username = '#{@username}'")
password = password[0]["password"]
password = BCrypt::Password.new(password)
@password == password
end
上面,我试图从SQL中检索加密密码(字符串格式),转换为Bcrypt对象并根据它验证密码。从理论上讲,假设输入的密码正确,该方法应返回true,但返回false。
问题可能是什么?
答案 0 :(得分:2)
进行身份验证时,您似乎没有对传入密码进行哈希处理。这是因为您正在执行@password == password
,其中@password
是纯文本String
密码(来自User#initialize
的{{1}})。
您应该翻转比较,以便使用BCrypt::Password#==
:post '/login'
。