使用BCrypt进行密码验证

时间:2017-11-02 17:55:15

标签: ruby sinatra bcrypt-ruby

我正在尝试使用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。

问题可能是什么?

1 个答案:

答案 0 :(得分:2)

进行身份验证时,您似乎没有对传入密码进行哈希处理。这是因为您正在执行@password == password,其中@password是纯文本String密码(来自User#initialize的{​​{1}})。

您应该翻转比较,以便使用BCrypt::Password#==post '/login'