带有jwt身份验证的django rest api正在请求csrf令牌

带有jwt身份验证的django rest api正在请求csrf令牌,django,authentication,django-rest-framework,jwt,Django,Authentication,Django Rest Framework,Jwt,我是django rest api框架的新手。我正在对rest api使用基于JWT令牌的身份验证,设置如下- REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.TokenAuthentication'

我是django rest api框架的新手。我正在对rest api使用基于JWT令牌的身份验证,设置如下-

    REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',

    )
}

AND

JWT_AUTH = {
    'JWT_ENCODE_HANDLER':
    'rest_framework_jwt.utils.jwt_encode_handler',

    'JWT_DECODE_HANDLER':
    'rest_framework_jwt.utils.jwt_decode_handler',

    'JWT_PAYLOAD_HANDLER':
    'rest_framework_jwt.utils.jwt_payload_handler',

    'JWT_PAYLOAD_GET_USER_ID_HANDLER':
    'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler',

    'JWT_RESPONSE_PAYLOAD_HANDLER':
    'rest_framework_jwt.utils.jwt_response_payload_handler',

    'JWT_SECRET_KEY': SECRET_KEY,
    'JWT_GET_USER_SECRET_KEY': None,
    'JWT_PUBLIC_KEY': None,
    'JWT_PRIVATE_KEY': None,
    'JWT_ALGORITHM': 'HS256',
    'JWT_VERIFY': True,
    'JWT_VERIFY_EXPIRATION': True,
    'JWT_LEEWAY': 0,
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
    'JWT_AUDIENCE': None,
    'JWT_ISSUER': None,

    'JWT_ALLOW_REFRESH': True,
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),

    'JWT_AUTH_HEADER_PREFIX': ('JWT','Bearer'),
    'JWT_AUTH_COOKIE': None,

}
基于此,我在chrome中使用了postman插件,并尝试使用以下步骤测试我的web api进行身份验证-

  • 我使用带有凭据的url来获取令牌

  • 我使用url并将步骤1中生成的令牌作为授权承载传递。这被定义为POST方法

  • 但当我这样做时,我得到错误->CSRF验证失败。请求被中止。HTTP 403错误


    你能告诉我这件事我做错了什么吗

    因为您是从提供数据的同一台机器发出请求,这将(相当恼人)导致CSRF异常。您需要在请求中包含一个CSRF令牌cookie,以表明请求是正确的

    所以你可以做两件事中的一件:

    • 使端点crsf免除
    • (推荐)获取crsf令牌并将其作为头附加到HTTP POST请求
    CSRF豁免 通过添加decorator,可以使各种端点csrf extempty

    from django.views.decorators.csrf import csrf_exempt
    class SomeView(APIView):
    
        @csrf_exempt
        def post(self, request):
            serializer = RegisterUserSerializer(data=request.data)
    
    请求代币 这一点有点痛苦(在我看来),因为您必须使用javascript:

    // 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');
    
    //使用jQuery
    函数getCookie(名称){
    var-cookieValue=null;
    if(document.cookie&&document.cookie!=''){
    var cookies=document.cookie.split(“;”);
    对于(变量i=0;i
    用于允许跨来源请求。步骤如下

  • 在已安装的应用程序中添加
    corsheaders
  • 在中间件中添加
    corsheaders.middleware.corsmidleware
  • 在设置中添加
    CORS\u ORIGIN\u ALLOW\u ALL=False

  • 进一步的设置可以在文档中看到。

    请记住,如果您从“”以外的任何位置向api发送请求,则(同源策略)[将生效并阻止该请求(标准CSRF保护)。请注意,即使运行在本地主机上但在不同端口上运行的web前端,也将被视为不同的来源。您需要启用CORS才能使其工作,如下面提到的@Muhammad Hassan。