Django 视图安全与最佳实践

5 投票
1 回答
4319 浏览
提问于 2025-04-15 21:49

我最近开始学习Django,现在我的应用快完成了,我开始考虑安全性和最佳实践的问题。

我有一个视图用来生成页面,页面中的不同功能会通过AJAX请求发送到各自的视图。例如,我有一个叫做show_employees的视图,我可以通过发送POST请求到delete_employee和update_employee视图来删除和更新员工信息。

  1. 我在每个视图前面加了@login_required装饰器,因为我不想让任何人在没有认证的情况下访问这些视图。这样做可以吗?

  2. 在delete_employee和update_employee视图中,我只在请求是AJAX的POST请求时才做出响应(使用is_ajax())。这样做可以吗?

  3. 当视图成功完成任务时,我返回一个“成功”的消息;如果表单有验证错误,我会返回一个错误信息,但我还没有处理其他异常。我应该怎么做?我是否应该通过AJAX响应返回标准的500错误页面,就像这个,通过用try-except块包裹视图来处理所有异常?

  4. 还有什么其他方法可以让我的视图更安全吗?

这是我的一个示例视图:

    @login_required
    def add_site(request):
        data = {}
        if request.method == 'POST':
            if request.is_ajax():
                form = AddSiteForm(request.user, request.POST)
                if form.is_valid():
                    site = form.save(commit=False)
                    site.user = request.user
                    site.save()
                    data['status'] = 'success'
                    data['html'] = render_to_string('site.html', locals(), context_instance=RequestContext(request))
                    return HttpResponse(simplejson.dumps(data), mimetype='application/json')
                else:
                    data['status'] = 'error'
                    data['errors'] = {}
                    for field, error in form.errors.iteritems():
                        data['errors']['id_'+field] = strip_tags(unicode(error))
                    return HttpResponse(simplejson.dumps(data), mimetype='application/json')

谢谢。

1 个回答

11

其实,除了只用 @login_required 这个装饰器,我建议你看看 权限框架 和相关的 权限要求装饰器。这样你可以更细致地控制用户或用户组的访问权限。用权限来管理用户行为比单纯用 login_required 装饰器要简单和安全得多。比如现在你只有管理员,但以后你想添加其他类型的用户,这时候如果不小心漏掉了 login_required 装饰器,就可能让那些用户也能访问管理员的页面。而如果你有合理定义的权限,就不会出现这个问题。

接下来,is_ajax 只是检查 HTTP_X_REQUESTED_WITH 这个头信息。这其实和安全性没什么关系,更像是为了用户体验。这样可以防止普通用户不小心在浏览器中打开那个页面,看到一些奇怪的数据。这对安全没有帮助,任何有技术的黑客都可以设置一个额外的 HTTP 头信息 :)。

不处理异常可能会很危险,如果你不小心把 DEBUG=True 留着,django 会提供一些代码片段和错误追踪信息,这可能会暴露出系统的弱点。不过,如果这个选项关闭了,django 会显示自己的 500 错误页面。我的建议是:找出所有预期的 django 异常(其实不多),确保你能正确处理这些异常。至于其他的异常,让 django 自己处理就好,django 仍然会提供生成错误追踪和其他调试信息的可能性,并把这些信息发送给管理员,而不是直接在页面上显示。如果你捕获了所有意外的错误,这种处理方式可能就无法直接使用,可能会让你对出错的代码一无所知。

最后,因为你在处理用户输入的数据,我建议你看看 django 书中的安全章节,它解释了最重要的威胁以及如何在 django 框架中处理这些威胁。

撰写回答