Rails“SessionsController#create 中没有方法错误”。显然是一个我不期望的 nil 对象,或者错误是这样说的

发布于 2024-11-16 18:16:43 字数 2989 浏览 4 评论 0原文

我正在尝试使用会话登录用户。我的控制器有一个“创建”会话方法:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风透绣罗衣 2024-11-23 18:16:43

我至少看到两个问题。

1) 不要在 :session 中查找 :email:password。它们应该位于 :params 哈希中,而不是位于 :params 内的 :session 哈希中。由于您没有获得正确的 :email,因此您永远找不到 User 记录,因此 User.authenticate 始终返回 nil。

2) 如果未找到电子邮件,User.authenticate 将返回 nil。如果找到电子邮件,则会返回 subscribed_pa​​ssword == 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 the User record, so User.authenticate always returns nil.

2) User.authenticate will return nil if the email isn't found. If the email is found, it returns the value of submitted_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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文