【问题标题】:How to protect Django's views functions from directly calling through browser url如何保护 Django 的视图函数不通过浏览器 url 直接调用
【发布时间】:2018-04-15 17:19:55
【问题描述】:

我想保护我的函数不直接通过浏览器 url 调用。可能通过 CSRF 是可能的。但我做不到。 在前端我使用 ajax 来调用这个函数。因此,调用应该只能通过 ajax 而不是直接来自浏览器 url。

我的javascript代码是

function getData(table,id){
data = []
$.ajax({
    type: "POST",
    url: "getData",
    dataType:'json',
    data:{'tableName':table},
    success: function(result) {

        for(var i=0;i<result.length;i++){

            for (var key in result[i]){
                val = result[i][key]

                if (data.indexOf(val)==-1){
                    data.push(val)
                }
            }                   
        }
        $( "#"+id ).autocomplete({
          source: data
        });

    }
});

}

所以我在 javascript 中调用这个函数。

在 urls.py 中

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^getData', views.getData, name='getData'),

]

在 Views.py 中

def getData(request):
    tableName = request.POST.get('tableName')
    tableName = 'colleges'
    cursor = connection.cursor()
    query = "select * from "+tableName
    cursor.execute(query)

    columnDesc = cursor.description
    result=[dict(zip([col[0] for col in columnDesc], row))
        for row in cursor.fetchall()]

    return HttpResponse(json.dumps(result), content_type="application/json")

所以,当我通过网络浏览器 url 直接调用时...

http://localhost/shikshapp/getData

我正在从我的观点中得到回应,我能够看到数据..

那么,我怎样才能保护这种调用..当令牌不存在时......但是这个调用应该可以通过 ajax 访问

【问题讨论】:

  • 尝试像 stackoverflow.com/questions/5100539/… 一样将 csrf 令牌添加到请求中,然后在视图中验证 csrf 是否匹配,然后处理 'request_csrf_token = request.META.get('HTTP_X_CSRFTOKEN', '')if request_csrf_token != csrf_token: return self._reject(request, REASON_BAD_TOKEN)
  • 我收到错误...全局名称 csrf_token 未定义 @Kalariya_M

标签: python ajax django python-2.7 django-csrf


【解决方案1】:

如果您只想接受 POST 请求,您可以将 require_http_methods 装饰器添加到您的视图中,如下所示:

@require_http_methods(["POST"])
def getData(request):
    tableName = request.POST.get('tableName')
    tableName = 'colleges'
    # ...

但是如果你想要一些安全性并防止自己受到 CSRF 攻击,你需要add a CSRF token:

# On the main view (the one that contains JS), add this decorator
@ensure_csrf_cookie
def yourView(request):
    pass
    # ...

# On the ajax view, refuse all requests without any csrf_token
@require_http_methods(["POST"])
@csrf_protect
def getData(request):
    tableName = request.POST.get('tableName')
    tableName = 'colleges'
    # ...

那么你的 JS 代码一定是这样的:

// function to get token from cookie with jQuery
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

// your function
function getData(table,id){
data = []
$.ajax({
    type: "POST",
    url: "getData",
    dataType:'json',
    data:{'tableName':table},
    beforeSend: function(xhr, settings) {
        // Add the CRSF header with the csrf cookie
        xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'););
    }
    success: function(result) {

        for(var i=0;i<result.length;i++){

            for (var key in result[i]){
                val = result[i][key]

                if (data.indexOf(val)==-1){
                    data.push(val)
                }
            }                   
        }
        $( "#"+id ).autocomplete({
          source: data
        });

    }
});

【讨论】:

    猜你喜欢
    • 2013-12-20
    • 2020-09-24
    • 2022-08-08
    • 2021-03-24
    • 2015-02-17
    • 2011-01-18
    • 2016-08-21
    • 2019-12-24
    • 2020-08-31
    相关资源
    最近更新 更多