一、Django的CSRF保护机制
1. 核心原理
作用 :防止跨站请求伪造(CSRF)攻击,确保表单提交来源可信。实现方式 : 在模板中使用{% csrf_token %}生成一个隐藏的<input>字段(如csrfmiddlewaretoken)和一个Cookie(csrftoken)。 提交表单时,Django会同时验证表单字段和Cookie中的token是否匹配。 中间件依赖 :由django.middleware.csrf.CsrfViewMiddleware实现,需在MIDDLEWARE配置中启用。
2. 关键流程
< form method= "post" > { % csrf_token % } < !- - 生成隐藏字段 - - > . . .
< / form>
生成阶段 :首次访问页面时,中间件生成token并注入响应(Cookie + 表单字段)。验证阶段 :提交表单时,中间件对比POST数据中的token和Cookie中的token,不一致则返回403错误。
3. 特殊场景处理
AJAX请求 :需手动从Cookie读取token并添加到请求头(X-CSRFToken)。豁免CSRF保护 :用@csrf_exempt装饰器标记视图(谨慎使用)。
二、redirect时附带locals()与不附带的区别
1. redirect函数的作用
返回HTTP重定向响应(状态码302),不直接渲染模板 ,而是跳转到新URL。 语法:redirect('view_name') 或 redirect('/url/')。
2. 错误用法:redirect(locals())
def my_view ( request) : user = request. usererror = "Invalid input" return redirect( 'success_page' , locals ( ) )
问题分析 : locals()返回当前作用域的所有变量(如user, error),但redirect不接受模板上下文参数 。实际效果:重定向时完全忽略 locals()中的变量,仅执行URL跳转。 若需传递数据,必须通过URL参数(?key=value)或Session实现。
3. 正确用法:render(request, template, locals())
def my_view ( request) : user = request. usererror = "Invalid input" return render( request, 'template.html' , locals ( ) )
与redirect的区别 : 场景 redirect(locals())render(request, template, locals())HTTP响应类型 302重定向 200 OK(直接渲染模板) 数据传递方式 无效(数据丢失) 有效(变量注入模板) URL变化 浏览器地址栏更新为目标URL 地址栏不变 典型用例 提交表单后跳转到结果页 渲染包含表单的页面
4. 重定向时传递数据的正确方法
三、最佳实践总结
CSRF安全 : 所有POST表单必须包含{% csrf_token %}。 避免全局禁用CSRF中间件,优先使用@csrf_exempt局部豁免。 重定向使用规范 : 禁止 在redirect中使用locals(),因其无法传递上下文。需传递数据时,改用Session或URL参数。 模板渲染优化 : 避免滥用render(..., locals()),显式传递变量更安全(如render(..., {'user': user}),防止意外暴露敏感变量。