首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails教程(由Michael Hartl编写),第9课,不能登录

Rails教程(由Michael Hartl编写),第9课,不能登录
EN

Stack Overflow用户
提问于 2012-11-14 05:28:27
回答 4查看 1.1K关注 0票数 1

我看过类似的错误,但不仅我的测试不会通过,脚本也不会在用户中注册。

失败: 在0.41649秒内完成31例,2例失败 失败的例子: rspec ./spec/controllers/sessions_controller_spec.rb:48 # SessionsController GET 'new‘SessionsController 'create’success应在rspec ./spec/controllers/sessions_controller_spec.rb:54 #SessionsController获取“新建”SessionsController“create”成功中签名,应重定向到“用户显示”页面 好了。 登录错误: NoMethodError in SessionsController#create 未定义的方法authenticate' for # Rails.root: /Users/lancevelasco/Development/appsample Application Trace | Framework Trace | Full Trace app/controllers/sessions\_controller.rb:10:in创建‘

代码

user.rb

代码语言:javascript
复制
# == Schema Information
#
# Table name: users
#
#  id                 :integer          not null, primary key
#  name               :string(255)
#  email              :string(255)
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#  encrypted_password :string(255)
#  salt               :string(255)
#

class User < ActiveRecord::Base
  attr_accessor   :password
  attr_accessible :email, :name, :password, :password_confirmation

  email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

  validates :name,  :presence => true,
                    :length   => { :maximum => 50 }
  validates :email, :presence   => true,
                    :format     => { :with => email_regex },
                    :uniqueness => { :case_sensitive => false }    
  validates :password, :presence => true,
                        :confirmation => true,
                        :length => { :within => 6..40 }

  before_save :encrypt_password

  def has_password?(submitted_password)
    encrypted_password == encrypt(submitted_password)
  end


  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

  def 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     
end  

sessions_controller.rb

代码语言:javascript
复制
 class SessionsController < ApplicationController

  def new
    @title = "Sign in"
  end

  def create
    user = User.authenticate(params[:session][:email],
                             params[:session][:password])
    if user.nil?
      flash.now[:error] = "Invalid email/password combination."
      render 'new'
    else
      sign_in user
      redirect_back_or user
    end
  end

  def destroy
    sign_out
    redirect_to root_path
  end
end

sessions_helper.rb

代码语言:javascript
复制
module SessionsHelper

  def sign_in_(user)
    cookies.permanent.signed[:remember_token] = [user.id, user.salt]
    current_user = user
  end

  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user || user_from_remember_token    
  end

  private

    def user_from_remember_token
      User.authenticate_with_salt()
    end

    def remember_token
      cookies.signed[:remember_token] || [nil,nil]
    end
end

user_controller_spec.rb

代码语言:javascript
复制
require 'spec_helper'

describe SessionsController do

  render_views

    describe "GET 'new'" do
    it "returns http success" do
      get 'new'
      response.should be_success
    end

    it "should have the right title" do
       get :new
       response.should have_selector('title', :content => "Sign in")
     end

     describe "POST 'create'" do

       describe "failure" do

          before(:each) do
            @attr = { :email => "", :password => ""}
          end 

          it "should re-render the new page" do
            post :create,  :session => @attr 
            response.should render_template('new')
          end

          it "should have the right title" do
            post :create, :session => @attr
          end

          it "should have an error message" do
            post :create, :session => @attr
            flash.now[:error].should =~ /invalid/i
          end
       end

       describe "success" do

         before(:each) do
           @user= Factory(:user)
           @attr = { :email => @user.email, :password => @user.password }
         end

         it "should sign the user in" do
           post :create, :session => @attr
           controller.current_user.should == @user
           controller.should  be_signed_in
         end

         it "should redirect to the user show page" do
           post :create, :session => @attr
           response.should redirect_to(user_path(@user))
         end

       end

     end
  end

end
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-11-14 06:07:01

据我所知,Michael曾经使用bcrypt来处理他的身份验证(密码),看起来他选择了放弃它并编写自己的身份验证(看起来确实是为了添加一个salt...very好的)。

在user.rb中有:

代码语言:javascript
复制
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

因此,正如您所看到的,您还需要将电子邮件传递给身份验证方法,而且由于它也捕获了用户,所以可以简化session#create方法。试试这个:

代码语言:javascript
复制
def create
  user = User.authenticate(params[:session][:email], params[:session][:password])
  if user.nil?
    flash.now[:error] = 'Invalid email/password combination'
    render 'new'
  else
    sign_in user
    redirect_back_or user
  end
end
票数 0
EN

Stack Overflow用户

发布于 2012-11-14 09:17:10

现在您调用了对用户对象的身份验证,但是如果我没记错的话,您就将身份验证声明为用户类的方法(例如,java中的静态方法),而不是用户的对象。这就是获得NoMethodError的原因,所以您应该使用类似于Kubee的方法:

代码语言:javascript
复制
user = User.authenticate(params[:session][:email], params[:session][:password])
票数 1
EN

Stack Overflow用户

发布于 2012-11-15 03:08:03

这是一个相当简单的解决办法。

在session_helper中

def sign_in_(用户)

应读

def sign_in(用户)

在application_controller中

添加包含SessionsHelper

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13373499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档