2013-11-04 73 views
0

我对Ruby on Rails相当陌生,所以如果这是一个简单的问题,请道歉,但经过数周的搜索解决方案之后,我觉得可能会更容易问一下。Rails 4 Active Record登录会话失败

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

如果我将cookie用于会话存储,但在将其切换到active_record时在后台打开某处,此示例正常工作。当我尝试登录时,它只是带我回到主页面,没有任何flash消息,也没有任何内容在我的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 %> 

型号/ 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

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

那固定的空裁判我得到,当我插入我的主网站似乎已经解决了这一问题(或者至少当我改变页面时它不会将我注销)。不知道它是如何修复它,但我会拿我能得到的。

初始化/ session_store.rb

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