{"title":"点击劫持保护","version":"6.1","locale":"zh-hans","docname":"ref/clickjacking","url":"/zh-hans/6.1/ref/clickjacking/","canonical":"https://djangodocs.dev/zh-hans/6.1/ref/clickjacking/","summary":"The clickjacking middleware and decorators provide easy-to-use protection against clickjacking . This type of attack occurs when a malicious site tricks a user into…","html":"<span id=\"clickjacking-protection\"></span><h1>点击劫持保护<a class=\"heading-anchor\" href=\"#module-django.middleware.clickjacking\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>The clickjacking middleware and decorators provide easy-to-use protection\nagainst <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Clickjacking\">clickjacking</a>. This type of attack occurs when a malicious site\ntricks a user into clicking on a concealed element of another site which they\nhave loaded in a hidden frame or iframe.</p>\n<section id=\"an-example-of-clickjacking\">\n<h2>点击劫持的一个例子<a class=\"heading-anchor\" href=\"#an-example-of-clickjacking\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Suppose an online store has a page where a logged-in user can click &quot;Buy Now&quot;\nto purchase an item. A user has chosen to stay logged into the store all the\ntime for convenience. An attacker site might create an &quot;I Like Ponies&quot; button\non one of their own pages, and load the store's page in a transparent iframe\nsuch that the &quot;Buy Now&quot; button is invisibly overlaid on the &quot;I Like Ponies&quot;\nbutton. If the user visits the attacker's site, clicking &quot;I Like Ponies&quot; will\ncause an inadvertent click on the &quot;Buy Now&quot; button and an unknowing purchase of\nthe item.</p>\n</section>\n<section id=\"preventing-clickjacking\">\n<span id=\"clickjacking-prevention\"></span><h2>防止点击劫持<a class=\"heading-anchor\" href=\"#preventing-clickjacking\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>现代浏览器尊重 <a class=\"reference external\" href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\">X-Frame-Options</a> HTTP 头，它表明是否允许在框架或 iframe 中加载资源。如果响应包含值为 <code class=\"docutils literal notranslate\"><span class=\"pre\">SAMEORIGIN</span></code> 的头，那么只有当请求来自同一个网站时，浏览器才会在框架中加载资源。如果头被设置为 <code class=\"docutils literal notranslate\"><span class=\"pre\">DENY</span></code>，那么无论请求是由哪个网站发出的，浏览器都会阻止资源在框架中加载。</p>\n<p>Django 提供了一些方法来在你的网站的响应中包含这个头：</p>\n<ol class=\"arabic simple\">\n<li><p>一个在所有响应中设置头的中间件。</p></li>\n<li><p>一组可用于覆盖中间件或仅为某些视图设置头的视图装饰器。</p></li>\n</ol>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">X-Frame-Options</span></code> HTTP 头只有在响应中还没有出现的情况下，才会被中间件或视图装饰者设置。</p>\n</section>\n<section id=\"how-to-use-it\">\n<h2>如何使用它<a class=\"heading-anchor\" href=\"#how-to-use-it\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"setting-x-frame-options-for-all-responses\">\n<h3>为所有响应设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">X-Frame-Options</span></code><a class=\"heading-anchor\" href=\"#setting-x-frame-options-for-all-responses\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>要为你的网站的所有响应设置相同的 <code class=\"docutils literal notranslate\"><span class=\"pre\">X-FrameOptions</span></code> 值，把 <code class=\"docutils literal notranslate\"><span class=\"pre\">'django.middleware.clickjacking.XFrameOptionsMiddleware'</span></code> 放到 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-MIDDLEWARE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">MIDDLEWARE</span></code></a>：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">MIDDLEWARE</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"o\">...</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;django.middleware.clickjacking.XFrameOptionsMiddleware&quot;</span><span class=\"p\">,</span>\n    <span class=\"o\">...</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>这个中间件在 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/django-admin/#django-admin-startproject\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">startproject</span></code></a> 生成的配置文件中启用了。</p>\n<p>默认情况下，中间件将为每个传出的 <code class=\"docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code> 设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">X-</span> <span class=\"pre\">Frame-Options</span></code> 头为 <code class=\"docutils literal notranslate\"><span class=\"pre\">DENY</span></code>。如果你想为这个头设置任何其他的值，可以设置 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-X_FRAME_OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">X_FRAME_OPTIONS</span></code></a> 配置：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">X_FRAME_OPTIONS</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;SAMEORIGIN&quot;</span>\n</code></pre></div>\n<p>在使用中间件时，有些视图可能 <strong>不希望</strong> 设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">X-</span> <span class=\"pre\">Frame-Options</span></code> 头。对于这些情况，你可以使用一个视图装饰器，告诉中间件不要设置头：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.clickjacking</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">xframe_options_exempt</span>\n\n\n<span class=\"nd\">@xframe_options_exempt</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">ok_to_load_in_a_frame</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;This page is safe to load in a frame on any site.&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>如果你想在框架或 iframe 中提交表单或访问会话 cookie，你可能需要修改 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-CSRF_COOKIE_SAMESITE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">CSRF_COOKIE_SAMESITE</span></code></a> 或 <a class=\"reference internal\" href=\"/zh-hans/6.1/ref/settings/#std-setting-SESSION_COOKIE_SAMESITE\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SESSION_COOKIE_SAMESITE</span></code></a> 配置。</p>\n</aside>\n</section>\n<section id=\"setting-x-frame-options-per-view\">\n<h3>为每个视图设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">X-Frame-Options</span></code>。<a class=\"heading-anchor\" href=\"#setting-x-frame-options-per-view\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>要在每个视图上设置 <code class=\"docutils literal notranslate\"><span class=\"pre\">X-Frame-Options</span></code> 头，Django 提供了这些装饰器：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.clickjacking</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">xframe_options_deny</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.decorators.clickjacking</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">xframe_options_sameorigin</span>\n\n\n<span class=\"nd\">@xframe_options_deny</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">view_one</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;I won&#39;t display in any frame!&quot;</span><span class=\"p\">)</span>\n\n\n<span class=\"nd\">@xframe_options_sameorigin</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">view_two</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;Display in a frame if it&#39;s from the same origin as me.&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>请注意，你可以将装饰器与中间件一起使用。使用装饰器可以覆盖中间件。</p>\n</section>\n</section>\n<section id=\"limitations\">\n<h2>限制<a class=\"heading-anchor\" href=\"#limitations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">X-Frame-Options</span></code> 头部仅能在 <a class=\"reference external\" href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options#browser_compatibility\">现代浏览器</a> 中防止点击劫持。</p>\n</section>","rootId":"module-django.middleware.clickjacking","toc":[{"title":"点击劫持的一个例子","anchor":"an-example-of-clickjacking","children":[]},{"title":"防止点击劫持","anchor":"preventing-clickjacking","children":[]},{"title":"如何使用它","anchor":"how-to-use-it","children":[{"title":"为所有响应设置 X-Frame-Options","anchor":"setting-x-frame-options-for-all-responses","children":[]},{"title":"为每个视图设置 X-Frame-Options。","anchor":"setting-x-frame-options-per-view","children":[]}]},{"title":"限制","anchor":"limitations","children":[]}],"breadcrumbs":[{"docname":"ref/index","title":"API 参考","url":"/zh-hans/6.1/ref/"}],"prev":{"docname":"ref/class-based-views/flattened-index","title":"基于类的通用视图——扁平化索引","url":"/zh-hans/6.1/ref/class-based-views/flattened-index/"},"next":{"docname":"ref/contrib/index","title":"contrib 包","url":"/zh-hans/6.1/ref/contrib/"},"formats":{"html":"/zh-hans/6.1/ref/clickjacking/","markdown":"/zh-hans/6.1/ref/clickjacking.md","json":"/zh-hans/6.1/ref/clickjacking.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/ref/clickjacking.txt","official":"https://docs.djangoproject.com/zh-hans/6.1/ref/clickjacking/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}