使用 BCrypt 进行密码验证
Password Authentication using BCrypt
我正在尝试使用 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
在上面,创建了一个新实例来传递用户名和密码。如果密码和确认密码匹配,密码方法将创建一个加密密码,插入方法将使用简单的SQL命令将用户名和加密密码插入数据库。
将用户名和加密密码插入数据库后。我想使用登录页面进行验证。我创建了一个新的 User 实例,将用户名和密码参数传递给如下所示的身份验证方法。该方法将查找与 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 对象并根据它验证密码。理论上,假设输入的密码正确,该方法应该 return 为真,但它 return 为假。
可能是什么问题?
您在进行身份验证时似乎没有对传入的密码进行哈希处理。这是因为您正在执行 @password == password
,其中 @password
是纯文本 String
密码(来自 User#initialize
来自 post '/login'
)。
您应该翻转比较,以便它使用 BCrypt::Password#==
:password == @password
。
我正在尝试使用 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
在上面,创建了一个新实例来传递用户名和密码。如果密码和确认密码匹配,密码方法将创建一个加密密码,插入方法将使用简单的SQL命令将用户名和加密密码插入数据库。
将用户名和加密密码插入数据库后。我想使用登录页面进行验证。我创建了一个新的 User 实例,将用户名和密码参数传递给如下所示的身份验证方法。该方法将查找与 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 对象并根据它验证密码。理论上,假设输入的密码正确,该方法应该 return 为真,但它 return 为假。
可能是什么问题?
您在进行身份验证时似乎没有对传入的密码进行哈希处理。这是因为您正在执行 @password == password
,其中 @password
是纯文本 String
密码(来自 User#initialize
来自 post '/login'
)。
您应该翻转比较,以便它使用 BCrypt::Password#==
:password == @password
。