Ruby Cuba框架中CSRF使用问题:csrf.safe?返回false及session丢失
问题解决步骤
1. 调整中间件加载顺序,确保会话中间件优先加载
Cuba::Safe插件依赖Rack会话机制,必须先加载会话中间件,再加载Safe插件。否则req.env["rack.session"]会是nil,直接导致CSRF验证失败。
# 先加载会话中间件,替换成你自己的高强度安全密钥 Cuba.use Rack::Session::Cookie, secret: "your_strong_secure_secret_here" # 再加载Safe插件 Cuba.plugin Cuba::Safe
2. 移除自定义session方法,使用Cuba内置方法
你在CSRF模块里自定义的session方法没有正确绑定Cuba的请求上下文,直接用Cuba内置的session方法即可——它已经封装了对req.env["rack.session"]的正确访问逻辑。修改后的CSRF模块:
class Cuba module Safe module CSRF def token session[:csrf_token] ||= SecureRandom.base64(32) end # 删除原来自定义的session方法 end end end
3. 确保POST请求携带正确的CSRF令牌
CSRF验证通过的前提是请求包含与会话中一致的令牌,两种实现方式:
- 在表单中添加隐藏字段:
<form method="post" action="/submit"> <input type="hidden" name="_csrf_token" value="<%= csrf.token %>"> <!-- 其他表单字段 --> </form> - 或在请求头中携带
X-CSRF-Token:fetch('/submit', { method: 'POST', headers: { 'X-CSRF-Token': '<%= csrf.token %>', 'Content-Type': 'application/json' }, body: JSON.stringify(data) })
4. 路由中验证会话状态
在POST路由里先确认会话是否正常初始化,避免nil问题:
Cuba.define do on post "submit" do halt 500, "Session unavailable" unless session unless csrf.safe? halt 403, "Invalid CSRF token" end # 处理业务逻辑 end end
内容的提问来源于stack exchange,提问作者user29559775
相关产品推荐
相关产品推荐

