Rails 4活动记录登录会话失败

时间:2013-11-04 00:02:57

标签: ruby session login ruby-on-rails-4 rails-activerecord

我对Ruby on Rails相当新,所以如果这是一个简单的问题就道歉,但经过数周寻找解决方案后,我觉得可能更容易提问。

我正在开发一个Rails 4网站,我想要基于active_record的身份验证。我在此示例之后模拟了注册和登录过程:http://railscasts.com/episodes/250-authentication-from-scratch?view=asciicast

如果我在会话存储中使用cookie,这个例子可以正常工作,但是当我将它切换到active_record时会在后台的某个地方中断。当我尝试登录时,它只是让我回到没有flash消息的主页面,而且我的current_user中没有任何内容(虽然我已经做了一个测试,我在登录页面上呈现新内容而不是重定向,它可以找到我的用户信息,但是一旦我离开,我就失去了会议)

由于文件大小限制,cookie会话无法正常工作,但我们对其他选项持开放态度。我已经设置了初始化器以指向active_records并且我已将它添加到gemfile中,但我似乎无法弄清楚它在哪里断开。我在某个地方错过了插入步骤以将其添加到db?

另一个可能的线索是,我的protect_from_forgery行给了我“无法验证CSRF令牌真实性”但如果我注释掉该行,会话仍然会失败。

如果这是一个非常简单的解决方案,我道歉,但就像我提到的那样,我一直在寻找解决方案。

以下是运行它的主要代码。如果您想查看更多代码,请告诉我。

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :null_session
  helper_method :current_user

  private
  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end
end

session_controller.rb

class SessionsController < ApplicationController
  def new
  end

  def create
    user = User.authenticate(params[:email], params[:password])
    if user
        session[:user_id] = user.id
        redirect_to root_url, :notice => "Logged in! #{User.find(session[:user_id]).email}"
    else
        flash.now.alert = "Invalid email or password"
        render "new"
    end
  end

  def destroy
    session[:user_id] = nil
    flash[:notice] = "Logged out!"
    redirect_to root_url #, :notice => "Logged out!"
  end
end

视图/会话/ new.html.erb

<h1>Log in</h1>

<%= form_tag sessions_path do %>
<p>
  <%= label_tag :email %><br />
  <%= text_field_tag :email, params[:email] %>
</p>

<p>
  <%= label_tag :password %><br />
  <%= password_field_tag :password %>
  <%= hidden_field_tag('authenticity_token', form_authenticity_token.to_s)%>

</p>

<p class="button"><%= submit_tag "Log in" %></p>
<% end %>

模型/ user.rb

class User < ActiveRecord::Base

attr_accessible :email, :password, :password_confirmation

attr_accessor :password
before_save :encrypt_password

validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email, :on => :create, :message => "Can't be blank"
validates_uniqueness_of :email

  def self.authenticate(email, password)
 user = find_by_email(email)
 if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
   user
 else
   nil
 end
  end

  def encrypt_password
 if password.present?
   self.password_salt = BCrypt::Engine.generate_salt
   self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
 end
   end 
end

1 个答案:

答案 0 :(得分:1)

当然,我会在发布后的第二天偶然发现修复,但我想分享我发现的其他人遇到同样问题的情况。我开始从我分享的示例中重新创建整个项目,看看我是否错过了一个步骤。当我运行该示例时,它开始给我一个null异常,说它试图创建一个没有数据的会话。我看了一下active_record github网站,在“问题”部分找到了这个链接 https://github.com/rails/activerecord-session_store/issues/6

修复了我得到的null ref,当我将它插入我的主站点时,似乎已经修复了问题(或者至少它在我更改页面时没有记录我)。不知道它是如何实际修复它的,但我会采取我能得到的东西。

初​​始化/ session_store.rb

ActiveRecord::SessionStore::Session.attr_accessible :data, :session_id