简体   繁体   English

Django @login_required 视图仍然显示用户何时通过返回 Chrome 上的历史记录而注销

[英]Django @login_required views still show when users are logged out by going back in history on Chrome

::Edit:: ::编辑::

@cache_control(no_cache=True, must_revalidate=True, no_store=True) FTW!!!!! @cache_control(no_cache=True, must_revalidate=True, no_store=True) FTW!!!!!!

Cache-Control: no-cache, no-store, must-revalidate did the trick. Cache-Control: no-cache, no-store, must-revalidate 做到了。 It took going to a few IRC chans and looking around but finally I got it to work.花了一些IRC chans并环顾四周,但最终我让它工作了。

::EDIT:: ::编辑::

I have a view where I'm setting @login_required on it and its secure for the most part, but if you have looked at the view then logout and just hit the back button in your browser you can view the content again with out being asked to login.我有一个视图,我在它上面设置了 @login_required 并且它在很大程度上是安全的,但是如果您查看了视图然后注销并点击浏览器中的后退按钮,您可以再次查看内容而不会被问到登录。 Though if you refresh the page the server with will redirect you.但是,如果您刷新页面,服务器将重定向您。

My suspension is its a cache issue where maybe I need to tell chrome not to store it in the history.我的暂停是一个缓存问题,也许我需要告诉 chrome 不要将它存储在历史记录中。

if you view a invoice for example then logout you can view the invoice again by selecting that page in your back history.例如,如果您查看发票然后注销,您可以通过在历史记录中选择该页面来再次查看发票。

I have tried this issue o firefox with no problem.我已经尝试过这个问题 o firefox 没有问题。 firefox asks for you to log back end so it must be a browser issue. firefox 要求您登录后端,因此它必须是浏览器问题。

You're right, this is cache problem.你是对的,这是缓存问题。

You can use cache_control decorator to force no cache on views[1]:您可以使用cache_control装饰器强制在视图 [1] 上不缓存:

from django.views.decorators.cache import cache_control

@cache_control(no_cache=True, must_revalidate=True, no_store=True)
def func()
  #some code
  return

You should also write your own decorator that replaces @login_required so that you don't need to use both on every page.您还应该编写自己的装饰器来替换@login_required这样您就不需要在每个页面上都使用两者。

[1] Disable browser 'Back' button after logout? [1] 注销后禁用浏览器的“返回”按钮?

This behavior is caused by a feature in Webkit browsers unofficially called Page Cache , also known as the back/forward cache.这种行为是由Webkit浏览器中一个非正式称为Page Cache的功能引起的,也称为后退/前进缓存。 It controls what happens to previous pages in the current browsing session.它控制当前浏览会话中先前页面发生的情况。 Webkit does something special in that it "suspends" previous pages. Webkit 做了一些特别的事情,因为它“暂停”了之前的页面。 It's as if the previous page is hidden in another tab;就好像上一页隐藏在另一个选项卡中一样; clicking the back button is like bringing the tab into the foreground.单击后退按钮就像将选项卡带到前台。 The page is still there just as it was.该页面仍然存在。 This means no network request is made and therefore your server logic is never touched.这意味着没有网络请求,因此你的服务器逻辑永远不会被触及。

You'll see this behavior in Safari as well as Chrome.您将在 Safari 和 Chrome 中看到这种行为。 Look at the Network Inspector panel and watch the network traffic when you click back to a page.查看 Network Inspector面板,并在单击返回页面时观察网络流量。 At a glance it looks like a request was made.乍一看,似乎是提出了请求。 Safari doesn't help dispel the notion that no request was actually made. Safari 无助于消除实际上没有提出任何请求的观念。 Chrome is more polite and tells you the page was loaded "(from cache)". Chrome 更礼貌,并告诉您页面已加载“(从缓存)”。 In Chrome, look at the size column or click the request and look at the Status Code in the Headers tab.在 Chrome 中,查看大小列或单击请求并查看标题选项卡中的状态代码 Of course the other indicator is how long the 'request' took in the Timeline (probably 0ms).当然,另一个指标是“请求”在时间轴中花费了多长时间(可能是 0 毫秒)。

That explains the behavior...now how to get around it.这解释了行为......现在如何解决它。 The best solution may just be a reminder on the logout page to close the browser window.最好的解决方案可能只是在注销页面提醒关闭浏览器窗口。

You've correctly determined that there's nothing you can do on the Django side.您已经正确地确定在 Django 方面您无能为力。 The cache decorators won't help you.缓存装饰器不会帮助你。 Unfortunately there doesn't appear to be a canonical answer to preventing Page Cache from stashing a page.不幸的是,似乎没有一个规范的答案来阻止页面缓存存储页面。 It also seems to be a feature in flux, so a solution now may just be a hack that won't work on later versions of Webkit.它似乎也是一个不断变化的功能,所以现在的解决方案可能只是一个 hack,不适用于更高版本的 Webkit。 Or Firefox may create a similar feature with different implementation.或者 Firefox 可能会创建具有不同实现的类似功能。

Serving your site over HTTPS with cache-control: no-store or cache-control: no-cache may do it but it's heavy handed for sure.使用cache-control: no-storecache-control: no-cache通过 HTTPS 为您的站点提供服务可能会这样做,但它肯定是繁重的。 One possible hack would be to set an unload/onunload event handler.一种可能的技巧是设置unload/onunload事件处理程序。

Read more about Page Cache behavior and the unload hack suggestion on these two Surfin' Safari articles.两篇Surfin' Safari 文章中阅读有关页面缓存行为和卸载黑客建议的更多信息。

UPDATE - @DigitalCake found that Cache-Control:no-store has some effect.更新- @DigitalCake 发现Cache-Control:no-store有一些影响。 In Django, this is accomplished with @cache_control(no_store=True) decorating the view.在 Django 中,这是通过@cache_control(no_store=True)装饰视图来完成的。 no store works in Chrome (v17.0.963.66) - the page is not stashed in Page Cache and the back button causes a network request. no store在Chrome(v17.0.963.66)的作品-网页没有在页面缓存藏匿和后退按钮导致网络请求。 no store does not work in Safari (v5.1.3). no store并不在Safari(v5.1.3)的工作 This shows that even across Webkit browsers Page Cache is implemented differently.这表明即使跨 Webkit 浏览器,页面缓存的实现方式也不同。 It demonstrates also the point that current work arounds are likely to be temporary hacks.它还证明了当前的变通方法可能是临时黑客的观点。

I tried this solution and it worked for me.我尝试了这个解决方案,它对我有用。

I had put both cashe control and login required.我已经同时要求现金控制和登录。

Here is the example这是例子

from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import cache_control

@cache_control(no_cache=True, must_revalidate=True, no_store=True)
@login_required(login_url='login')
def myview(request):
   return HttpResponse(render(request,'path_to_your_view.html'))

March 2020 update: Adding to the accepted answer, the Django 3.0 docs show a never_cache decorator. 2020 年 3 月更新:添加到已接受的答案中,Django 3.0 文档显示了一个never_cache装饰器。

It adds a Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private header to the response.它向响应添加了一个Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private header。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM