默认情况下,所有rails控制器都会继承应用程序控制器。
在我的应用程序中,我希望用户能够使用http-basic auth从任何页面进行身份验证,并通过发布进行身份验证,但仅限于一个控制器。
目前看起来像这样(简化):
class ApplicationController < ActionController::Base
before_filter :set_current_user
private
def set_current_user
Authorization.current_user = current_user
end
def current_user
if session[:user].blank?
authenticate_or_request_with_http_basic do |user,pass|
session[:user] = authenticated_user_or_nil
end
end
session[:user]
end
end
class UserSessionsController < ApplicationController
prepend_before_filter :set_user_from_params
private
def set_user_from_params
session[:user] = authenticated_user_or_nil
end
end
我在set_user_from_params
和set_current_user
都设置了一个断点,并确认它们确实以正确的顺序被调用。
set_user_from_params
实际上是正确设置session[:user]
,但是当我继续并点击set_current_user
内的断点时,会话哈希为空!?
这是预期的行为还是我错过了一些非常明显的事情?
答案 0 :(得分:2)
如果请求是post请求,那么默认情况下rails会检查是否存在有效的csrf令牌。
插入before_filter
进行检查,如果失败,则rails会重置会话,这与您的情况一致。
您需要确保您的帖子请求包含真实性令牌,或者(如果适用)通过跳过verify_authenticity_token
过滤器来禁用该检查。
验证的一种方法是添加
def handle_unverified_request 超 Rails.logger.info“处理未经验证的请求 - csrf问题” 端
到您的控制器。如果问题是csrf问题,那么将调用此方法,并将写入日志文件,确认已发生这种情况。