Python 学习笔记

编写上下文处理器

2018-02-06  本文已影响20人  大爷的二舅

编写自己的上下文处理器指南
上下文处理器有一个非常简单的接口:它只是一个Python函数,它接受一个参数,一个HttpRequest对象,并返回一个被添加到模板上下文的字典。 每个情境处理器必须返回一个字典。 这里有一些关于你自己的技巧:

自动HTML转义

从模板生成HTML时,总是存在一个变量将包含影响生成的HTML的字符的风险。 例如,考虑这个模板片段:

Hello, {{ name }}.

起初,这似乎是一个无害的方式来显示用户的名字,但考虑如果用户输入他的名字会发生什么,如下所示:

<script>alert('hello')</script>

有了这个名字值,这个模板会被渲染为:

Hello, <script>alert('hello')</script>

这意味着浏览器会弹出一个JavaScript警告框! 同样,如果名称包含一个“<”符号,像这样?

<b>username 

这将导致这样的渲染模板:

Hello, <b>username 

...这反过来又会导致网页的其余部分被加粗! 显然,用户提交的数据不应该盲目地被信任,并直接插入到您的网页中,因为恶意用户可能会使用这种漏洞做可能的坏事。

这种类型的安全漏洞被称为跨站点脚本(XSS)攻击。 (有关安全性的更多信息,请参阅第19章)。 为了避免这个问题,你有两个选择:

默认情况下,在Django中,每个模板都会自动转义每个变量标签的输出。 具体来说,这五个字符是逃脱的:

我们再一次强调,这种行为默认是开启的。 如果您使用的是Django的模板系统,那么您将受到保护。

如何关闭它

如果您不希望在每个站点,每个模板级别或每个变量级别上自动转义数据,则可以通过多种方法关闭数据。 你为什么要把它关掉? 因为有时,模板变量包含的数据,你打算被呈现为原始的HTML,在这种情况下,你不希望他们的内容被转义。

例如,您可能会在数据库中存储一个受信任的HTML块,并希望将其直接嵌入到您的模板中。 或者,您可能正在使用Django的模板系统来生成不是HTML的文本 - 比如电子邮件。

对于个体变量

要禁用单个变量的自动转义,请使用安全筛选器:

This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}

认为安全是避免进一步转义的安全速度,或者可以安全地解释为HTML。 在这个例子中,如果数据包含'<b>',输出将是:

This will be escaped: &lt;b&gt;
This will not be escaped: <b>
对于模板块

要控制模板的自动转义,请将模板(或模板的特定部分)包装在autoescape标记中,如下所示:

{% autoescape off %}
    Hello {{ name }}
{% endautoescape %}

autoescape标签将其作为参数打开或关闭。 有时,您可能会强制自动转义,否则将被禁用。 这是一个示例模板:

Auto-escaping is on by default. Hello {{ name }}

{% autoescape off %}
    This will not be auto-escaped: {{ data }}.

    Nor this: {{ other_data }}
    {% autoescape on %}
        Auto-escaping applies again: {{ name }}
    {% endautoescape %}
{% endautoescape %}

自动转义标签将其作用扩展到扩展当前标签的模板以及通过包含标签包含的模板,就像所有块标签一样。 例如:

# base.html

{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}

# child.html

{% extends "base.html" %}
{% block title %}This & that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}

由于在基本模板中关闭了自动转义,所以在子模板中也将关闭自动转义,当greeting变量包含字符串<b> Hello!</ b>时,会生成以下呈现的HTML:

<h1>This & that</h1>
<b>Hello!</b>

一般来说,模板作者不需要担心很多自动转义。 Python方面的开发人员(编写视图和自定义过滤器的人)需要考虑数据不应该被转义的情况,并适当地标记数据,以便在模板中工作。

如果您创建的模板可能在您不确定是否启用了自动转义的情况下使用,则可以将转义筛选器添加到任何需要转义的变量。 打开自动转义时,转义过滤器不会有双转义数据的危险 - 转义过滤器不会影响自动转义的变量。

自动转义过滤参数中的字符串文字

正如我们前面提到的,过滤器参数可以是字符串:

{{ data|default:"This is a string literal." }}

所有字符串文字都插入,没有任何自动转义到模板 - 它们的行为就好像它们都通过了安全过滤器。 这背后的原因是模板作者控制了字符串文字的内容,因此他们可以确保在写入模板时正确地转义文本。

这意味着你会写

{{ data|default:"3 &lt; 2" }}

而不是

{{ data|default:"3 < 2" }} <== Bad! Don't do this.

这并不影响来自变量本身的数据。 如有必要,变量的内容仍然会自动转义,因为它们超出了模板作者的控制范围。

上一篇下一篇

猜你喜欢

热点阅读