我对 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