Rails“SessionsController#create 中没有方法错误”。显然是一个我不期望的 nil 对象,或者错误是这样说的
我正在尝试使用会话登录用户。我的控制器有一个“创建”会话方法:
def create
user = User.authenticate(params[:session][:email], params[:session][:password])
if user.nil?
#create an error message and re-render the signin form
flash.now[:error] = "Invalid email/password combination"
@title = "Sign in"
render 'new'
else
#sign in user and redirect to the user's show page
sign_in user
redirect_to user
end
end
类方法“验证”始终返回 null。我使用控制台在“nil?”处创建用户返回 false,然后我调用“authenticate”,它每次都返回 nil。我不知道为什么,我已经研究了好几个小时了。起初我以为这是我将参数传递给authenticate方法的方式,但这些应该是正确的,并且由于auth方法甚至无法在具有常规值的控制台中工作,它可能不是参数而是“authenticate”的结构'。这是“authenticate”方法及其辅助方法:
#defining a class method for "User" to authenticate a user who submits an email and password
def User.authenticate(email, submitted_password)
user = find_by_email(email)
return nil if user.nil?
return user if user.has_password?(submitted_password)
end
# Return true if the user's password matches the submitted password.
def has_password?(submitted_password)
encrypted_password == encrypt(submitted_password)
end
def self.authenticate_with_salt(id, cookie_salt)
user =find_by_id(id)
(user && user.salt == cookie_salt) ? user : nil
end
private
def encrypt_password
self.salt = make_salt if new_record?
self.encrypted_password = encrypt(password)
end
def encrypt(string)
secure_hash("#{salt}--#{string}")
end
def make_salt
secure_hash("{#Time.now.utc}--#{password}")
end
def secure_hash(string)
Digest::SHA2.hexdigest(string)
end
有人知道这是怎么回事吗?我很乐意提供更多信息。我四处寻找可能的解决方案,但找不到任何解决方案。
sign_in(user) 方法和辅助方法内容:
module SessionsHelper
def sign_in(user)
#set cookie permanently
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
#define "current_user" so it can be used all over the place
self.current_user = user
end
def current_user=(user)
@current_user = user
end
def current_user
@current_user ||= user_from_remember_token
end
def signed_in?
!current_user.nil?
end
def sign_out
cookies.delete(:remember_token)
@current_user = nil
end
private
def user_from_remember_token
User.authenticate_with_salt(*remember_token)
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
end
users_controller:
class UsersController < ApplicationController
# GET requests are automatically handled by the "show" action.
def show
@user = User.find(params[:id])
@title = @user.name
end
def new
@user = User.new
@title = "Sign up"
end
def create
@user = User.new(params[:user])
if @user.save
sign_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
@title = "Sign up"
render 'new'
end
end
end
I am trying to sign in users with sessions. My controller has a method 'create' sessions:
def create
user = User.authenticate(params[:session][:email], params[:session][:password])
if user.nil?
#create an error message and re-render the signin form
flash.now[:error] = "Invalid email/password combination"
@title = "Sign in"
render 'new'
else
#sign in user and redirect to the user's show page
sign_in user
redirect_to user
end
end
the class method 'authenticate' always returns null. I uses the console to create users where 'nil?' returns false, and then I call 'authenticate' and it returns nil, everytime. I don't know why and have pored over it for hours. At first I thought it was the way I was passing the parameters to the authenticate method, but those should be right, and since the auth method doesn't even work in console with regular values it probably isnt the parameters but the structure of 'authenticate'. Here is the 'authenticate' method and its helper methods:
#defining a class method for "User" to authenticate a user who submits an email and password
def User.authenticate(email, submitted_password)
user = find_by_email(email)
return nil if user.nil?
return user if user.has_password?(submitted_password)
end
# Return true if the user's password matches the submitted password.
def has_password?(submitted_password)
encrypted_password == encrypt(submitted_password)
end
def self.authenticate_with_salt(id, cookie_salt)
user =find_by_id(id)
(user && user.salt == cookie_salt) ? user : nil
end
private
def encrypt_password
self.salt = make_salt if new_record?
self.encrypted_password = encrypt(password)
end
def encrypt(string)
secure_hash("#{salt}--#{string}")
end
def make_salt
secure_hash("{#Time.now.utc}--#{password}")
end
def secure_hash(string)
Digest::SHA2.hexdigest(string)
end
Anyone know what the deal is? and I am happy to supply anymore information. I searched around for potential solutions, and couldn't find any.
sign_in(user) method and helper methods stuff:
module SessionsHelper
def sign_in(user)
#set cookie permanently
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
#define "current_user" so it can be used all over the place
self.current_user = user
end
def current_user=(user)
@current_user = user
end
def current_user
@current_user ||= user_from_remember_token
end
def signed_in?
!current_user.nil?
end
def sign_out
cookies.delete(:remember_token)
@current_user = nil
end
private
def user_from_remember_token
User.authenticate_with_salt(*remember_token)
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
end
users_controller:
class UsersController < ApplicationController
# GET requests are automatically handled by the "show" action.
def show
@user = User.find(params[:id])
@title = @user.name
end
def new
@user = User.new
@title = "Sign up"
end
def create
@user = User.new(params[:user])
if @user.save
sign_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
@title = "Sign up"
render 'new'
end
end
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我至少看到两个问题。
1) 不要在
:session
中查找:email
和:password
。它们应该位于:params
哈希中,而不是位于:params
内的:session
哈希中。由于您没有获得正确的:email
,因此您永远找不到User
记录,因此User.authenticate
始终返回 nil。2) 如果未找到电子邮件,
User.authenticate
将返回nil
。如果找到电子邮件,则会返回subscribed_password == crypto_password
的值。您有三种可能的返回值(nil、true、false),但只有两个控制路径,一种用于 nil(未找到记录),另一种用于所有其他情况,因此无论密码测试结果如何,您都可以登录用户。I see at least two problems.
1) Don't look for the
:email
and:password
in the:session
. They should be in the:params
hash, not in the:session
hash inside:params
. Since you aren't getting the correct:email
, you never find theUser
record, soUser.authenticate
always returns nil.2)
User.authenticate
will returnnil
if the email isn't found. If the email is found, it returns the value ofsubmitted_password == encrypted_password
. You have three possible return values (nil, true, false), but only two control paths, one for nil (record not found) and one for all other cases, so you log the user in regardless of the password test result.