Django restful 403解决办法

用了Django的restful,但在访问url的时候遇到403错误:

image.png

为什么这个错误发生?

这是由于SessionAuthenticationDRF使用的默认方案。DRF SessionAuthentication使用Django的会话框架进行认证,这需要检查CSRF。

由于DRF需要同时支持基于会话和非基于会话的身份验证,因此它只对经过身份验证的用户执行CSRF检查。这意味着只有经过身份验证的请求才需要CSRF令牌,而匿名请求可能会在没有CSRF令牌的情况下发送。

如果您在SessionAuthentication中使用AJAX风格的API,则需要为任何“不安全”HTTP方法调用(如PUT, PATCH, POST or DELETE请求)包含有效的CSRF令牌。

  • 所以要么不使用django_rest_framework的session,此时在REST_FRAMEWORK中注释调session即可
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        # 'rest_framework.authentication.TokenAuthentication',
        # 'rest_framework.authentication.SessionAuthentication',
    ),
}
  • 有些情况下,我们必须得使用session认证,这种情况下的解决办法有:
  • 前端每个请求加csrf的token
// using 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;
}

var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

然后ajax的请求携带csrftoken

$.ajax({
    method: 'POST',
    url: 'your.url.com/',
    beforeSend: function(xhr, settings) {
        if (!WU._csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    },
    success: function(msg)
    {}
});
  • django中间键

新建middleware.py

class DisableCSRF(object):
    def process_request(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)

然后在settings.py中将该中间键添加到MIDDLEWARE_CLASSES

MIDDLEWARE_CLASSES = [
    ...
    'app.middleware.DisableCSRF',
]

此时,再去访问url,就不会遇到403的错误了。

你可能感兴趣的:(Django restful 403解决办法)