Rails(set_no_cache方法)无法在Safari和Opera中禁用浏览器缓存

12

在使用Devise进行身份验证后,我发现存在一个安全漏洞,即用户注销后,会话变量仍保留。这使得任何人都可以按返回按钮并访问已登录用户的先前屏幕。

我查看了这些文章 Num 1 Num 2 Num 3

我将以下行添加到我的application_controller中:

before_filter :set_no_cache
def set_no_cache
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end

在 _form.html.erb 文件的顶部,我添加了以下内容

<%if user_signed_in? %>
<%=link_to "Sign Out",  destroy_user_session_path, :method => :delete %><br/>
<%= form_for(@listing) do |f| %>
<% if @listing.errors.any? %>
...........

然后我在Firefox、Chrome和Safari上测试了应用程序。

Firefox和Chrome都没有问题,因为我注销并点击了后退按钮,无法看到用户的上一个屏幕,但是,在Safari和Opera中,不安全的行为仍然存在。这段代码没有任何效果。

有什么建议可以解决这个问题吗?

谢谢


这是 https://dev59.com/ME3Sa4cB1Zd3GeqPy-TA 的副本。 - hallvors
嗯。看了这个链接。它完全没有讲到Safari,只提到了Opera。而且我已经尝试了他们上面列出的所有解决方案,就像你在上面看到的那样。 - banditKing
哦,你说的关于Safari的是对的。问题中只有“Opera”部分是真正的重复,因为那里的回答解释了为什么Opera会这样,并且唯一真正的解决方法是使用https和must-revalidate。 - hallvors
好的,非常感谢。我已经成功解决了Safari的问题。但是对于Opera,我会记下你的建议。非常感谢 :) - banditKing
有人知道如何在Rails 3.2.20中做这个吗?http://stackoverflow.com/questions/26994714/how-to-force-cache-control-to-no-store-in-rails-3-2-20 - equivalent8
3个回答

13

我遇到了同样的问题,并找到了一个好的解决方案并将其记录在博客中:

http://www.fordevs.com/2011/10/how-to-prevent-browser-from-caching-a-page-in-rails.html

要添加“no-cache”,请在application_controller.rb文件中添加以下行:

before_filter :set_no_cache

以及函数

def set_no_cache
    response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
    response.headers["Pragma"] = "no-cache"
    response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end

这在Safari中不起作用,但在Chrome和Firefox中可以。 - joeyk16
您还可以查看 no_cache_control gem,它会自动将这些头添加到所有请求中:https://github.com/equivalent/no_cache_control - Joshua Pinter
gem no_cache_control 正好做了被接受的答案提到的事情。不需要为三行代码添加一个gem。 - Vivek Tripathy

1

首先,对于任何缓存问题,请使用Mark Nottingham的HTTP缓存指南

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

试试这个。


0
我发现在我的应用控制器中这样做对开发非常有帮助。
after_filter  :expire_for_development

protected

def expire_for_development
  expires_now if Rails.env.development?
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接