0

我对 Ruby on Rails 还很陌生,如果这是一个简单的问题,我深表歉意,但经过数周的寻找解决方案后,我觉得问起来可能更容易。

我正在一个 Rails 4 站点上工作,我希望在该站点上进行基于 active_record 的身份验证。我在这个例子之后模拟了注册和登录过程:http ://railscasts.com/episodes/250-authentication-from-scratch?view=asciicast

如果我将 cookie 用于会话存储,则此示例可以正常工作,但是当我将其切换到 active_record 时,它会在后台某处中断。当我尝试登录时,它只是将我带回主页,没有闪烁消息,并且我的 current_user 中没有任何内容(尽管我已经做了一个测试,我在登录页面上呈现新而不是重定向,它可以找到我的用户信息,但是一旦我离开,我就会失去会话)

由于文件大小限制,cookie 会话将无法工作,但我们对其他选项持开放态度。我已经将初始化程序设置为指向 active_records 并将其添加到 gemfile 中,但我似乎无法弄清楚它在哪里中断。我是否在某处缺少插入步骤以将其添加到数据库中?

另一个可能的线索是我的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 %>

模型/用户.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
4

1 回答 1

1

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

这修复了我得到的空引用,当我将它插入我的主站点时,它似乎已经解决了问题(或者至少在我更改页面时它不会让我退出)。不知道它实际上是如何修复它的,但我会尽我所能。

初始化程序/session_store.rb

ActiveRecord::SessionStore::Session.attr_accessible :data, :session_id
于 2013-11-05T00:02:19.353 回答