我对ruby和rails相对较新,如果我的任何代码有点乱或者不遵循一般约定,那就很抱歉。欢迎提出任何意见。
我尝试使用BCrypt创建用户/密码身份验证系统但是当我去检查密码时,它总是会失败。
User.rb
#encryption of password
before_save :encrypt_password
after_save :clear_password
def encrypt_password
if password.present?
self.password_hash = Password.create(password)
end
end
def clear_password
self.password = nil
end
#authentication
def self.authenticate(username_or_email="", login_password="")
if EMAIL_REGEX.match(username_or_email)
user = User.find_by_email(username_or_email)
else
user = User.find_by_username(username_or_email)
end
if user && user.password_hash == login_password
return user
else
return false
end
end
users_controller.rb
def new
@user = User.new
end
def create
@user = User.new( user_params )
if @user.save
flash[:notice] = "You've signed up successfully"
flash[:color] = "valid"
else
flash[:notice] = "Form is invalid"
flash[:color] = "invalid"
end
render "new"
end
sessions_controller.rb
def login_attempt
authorized_user = User.authenticate(params[:username_or_email], params[:login_password])
if authorized_user
session[:user_id] = authorized_user.id
@current_user = authorized_user
logger.debug "User has been authorized"
flash[:notice] = "Welcome again, you logged in as #{authorized_user.username}"
redirect_to(:action => 'home')
else
flash[:notice] = "Invalid Username or Password"
flash[:color] = "invalid"
render "login"
end
end
任何帮助都将不胜感激,谢谢。
答案 0 :(得分:0)
我打赌问题是将存储密码的哈希与普通密码字符串进行比较:
def login_attempt
authorized_user = User.authenticate(params[:username_or_email], params[:login_password])
和
def self.authenticate(username_or_email="", login_password="")
...
if user && user.password_hash == login_password
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
您可能需要修复与的比较。
您只需确保user.password_hash == Password.new(login_password)
login_password
不包含某些尾随字符(如换行符)或self.password_hash
在此期间不会被更改。
还注意到clear_password
方法中的可能拼写错误 - self.password = nil
而不是self.password_hash = nil
。
作为旁注,我会将身份验证留给某些成熟模块,例如Devise(警告:需要启用javascript)
答案 1 :(得分:0)
所以我找到了一种不同的方法来使用BCrypt。 Rails有一个内置的has_secure_password
,如果users表中的列被称为password_digest
,它就可以工作。它的工作原理如下:
<强> sessions_controller.rb 强>
def login_attempt
if EMAIL_REGEX.match(params[:username_or_email])
user = User.find_by_email(params[:username_or_email])
else
user = User.find_by_username(params[:username_or_email])
end
authorized_user = user.authenticate(params[:login_password])
if authorized_user
session[:user_id] = authorized_user.id
@current_user = authorized_user
redirect_to(:action => 'home')
else
flash[:notice] = "Invalid Username or Password"
flash[:color] = "invalid"
render "login"
end
end
并且在 user.rb 类文件中必须有一行代码:
has_secure_password