我的 django 模板布尔变量在 javascript 中没有按预期工作
Posted
技术标签:
【中文标题】我的 django 模板布尔变量在 javascript 中没有按预期工作【英文标题】:My django template boolean variable isn't working as expected in javascript 【发布时间】:2012-09-05 21:51:01 【问题描述】:这是我的 base.html 标头中的代码
<script>
var auth_status = " user.is_authenticated "
</script>
% block scripts % % endblock %
我网站中的其余脚本都在块脚本中。
在子模板中(在脚本块内和脚本标签内)我有这段代码,
if (auth_status)
//something
手头的错误是 auth_status 始终为 True,它应该在何时打开和关闭取决于用户是否登录。Request_context 正在传递给模板,因此这不应该是错误。
谢谢
【问题讨论】:
与您的问题看似无关,但请注意,如果您确实依赖此 JS 变量的值,则执行if (user_is_authenticated) do stuff;
可能会成为安全问题。用户可以在执行前修改 JS 变量的值。
所以你说用户可以以某种方式设置auth_status = true?那么绕过 js var 是一个有效的解决方法吗?例如:if( user.is_authenticated|yesno:"true,false" ) 与 if(auth_status) ??
恶意用户可能只是拉取您页面的源代码,然后用...替换他们想要的任何内容。 没有方法可以实现任何安全客户端(即在JS中)并且没有没有解决方法,所有安全/访问控制必须在服务器端(即在您的 Python 代码中)完成。 JS 不是动态执行的应用程序代码的扩展,它是不同的东西,具有不同的约束。
等等,所以即使是 django 的模板变量也有被人篡改的风险?一个合理的解决方案是让任何需要 user_auth 成为 html POST 的东西?
是的,您可以在 python 代码中安全地使用request.user.is_authenticated()
。可以在模板代码中使用% if user.authenticated %
,因为这将在服务器端计算,即在 HTML 发送到客户端之前。一般的经验法则是可以更改到达客户端的任何内容,而无法更改的内容则不能。 (至少,不是这样;))
【参考方案1】:
另一种选择是使用 jinja2 tojson
过滤器:
<script>
let javascript_var = python_var|tojson ;
</script>
您可能还想使用 safe
过滤器,具体取决于您传递的内容:
<script>
let javascript_var = python_var|tojson|safe ;
</script>
【讨论】:
【参考方案2】:我看到你的auth_status
变量似乎是一个字符串,而不是一个布尔值。 javascript 上具有非空字符串的变量将在 if
子句上计算为 true
。
总之,像
<script>
var auth_status = user.is_authenticated ;
</script>
不会工作,因为这会生成这个 HTML:
<script>
var auth_status = True;
</script>
因为 Python 的 True 布尔值是大写的。
这应该完成从 Python 到 Javascript 的翻译:
<script>
var auth_status = user.is_authenticated|yesno:"true,false" ;
</script>
在此处查看 yesno 文档:https://docs.djangoproject.com/en/dev/ref/templates/builtins/#yesno
【讨论】:
哇!非常感谢,我完全忽略了两种语言的大写/小写差异! 将 Python 变量传递给 JS 变量的更通用的解决方案是使用 json。在 py 中:上下文 ['foo'] = json.dumps(a_py_list)。在模板 中。这适用于大多数数据结构,也适用于布尔值。 @Sean 我不认为在您第一次将值放入context
时使用 json
将 Python 值转储到 Javascript 安全的表示中是一个好主意,因为您例如,在处理程序中不能确定它是用作 JS 值还是用作 Jinja 模板中的 Python。如果在我的 Jinja 模板中我想使用像 % if myBool %
这样的代码,如果 myBool
具有字符串值而不是 Python 布尔值,它将无法正常工作。
@Jesse:我没想到会有混淆,但你是对的。我应该澄清一下,我只对 JS 中需要的变量执行此操作,而不是上下文中的所有变量。通常它是将更复杂的数据聚合到单个字典中,在 JS 中它成为一个对象。您是否知道另一种解决在初始页面加载时将后端变量传递给 JS 的一般问题的方法?不是 ajax 应用程序,只是一次加载,然后是一些需要使用来自服务器的数据进行初始化的 JS。以上是关于我的 django 模板布尔变量在 javascript 中没有按预期工作的主要内容,如果未能解决你的问题,请参考以下文章