【问题标题】:Django-rest-framework api add SessionAuthentication as optionalDjango-rest-framework api 添加 SessionAuthentication 作为可选
【发布时间】:2020-01-25 04:37:24
【问题描述】:

嗨,我目前有我的 api,它使用这个 simple-JWT 包进行 jwt 令牌身份验证,效果很好。但是现在当我尝试使用 Ajax 从 django 网站应用程序调用 api 时,其中来自已经登录的页面用户,但它仍然需要我使用 jwt access_token。

页面用户已经登录我的 ajax 调用:

$.ajax({
       type: "POST",
       url: "/api/add_favorite/" + property_id + "/",
       beforeSend: function (xhr) {
              xhr.setRequestHeader('Authorization', 'Bearer {{ refresh_token }}');
       },
       success: function (data) {
       if (data.code == 200) {
              alert('added to favorite');
              replace_part_1 = '<a id="mylink2" href="#" value="' + property_id +'"><i class="fas fa-heart fa-lg" style="color: red" title="Remove from favorite"></i></a>'
              $("a[value='" + property_id + "']").replaceWith(replace_part_1);
             }
       }
});

现在我不想设置带有授权的标题,因为在页面中用户已经登录,所以会话已经设置。

所以我尝试像这样将 Django Session 身份验证添加到 api:

@api_view(['POST'])
@authentication_classes([SessionAuthentication, JWTAuthentication])
@permission_classes([IsAuthenticated])
def add_favorite(request, property_id):
    if request.method == 'POST':
        try:
            favorite_property = Property.objects.get(pk=property_id)
            if request.user.is_authenticated:
                login_user = request.user
                if not login_user.properties.filter(pk=property_id).exists():
                    login_user.properties.add(favorite_property)

                    return JsonResponse({'code':'200','data': favorite_property.id}, status=200)
                else:
                    return JsonResponse({'code':'404','errors': "Property already exists in favorite"}, status=404)

        except Property.DoesNotExist:
            return JsonResponse({'code':'404','errors': "Property not found"}, status=404)

删除标题后我的 Ajax :

$.ajax({
       type: "POST",
       url: "/api/add_favorite/" + property_id + "/",
       },
       success: function (data) {
       if (data.code == 200) {
              alert('added to favorite');
              replace_part_1 = '<a id="mylink2" href="#" value="' + property_id +'"><i class="fas fa-heart fa-lg" style="color: red" title="Remove from favorite"></i></a>'
              $("a[value='" + property_id + "']").replaceWith(replace_part_1);
             }
       }
});

我从 Ajax 调用中删除了 set 标头,现在我得到 403 返回码:

加载资源失败:服务器响应状态为 403 (禁止)

我的设置:

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    # 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

我不知道为什么会话身份验证不起作用,因为 Ajax 调用来自已登录的页面用户。

感谢阅读!

【问题讨论】:

    标签: python django django-rest-framework django-authentication


    【解决方案1】:

    因为您在 ajax 请求中添加了Authentication 标头,如果请求标头中存在Authentication,Django 会自动使用TokenAuthentication。删除它以使用 SessionAuthentication。

    当你切换到使用 SessionAuthentication 时可能会出现一个问题,如果没有 CSRF 令牌,Django 将拒绝你的 unsafe 请求,更详细的 here

    【讨论】:

    • 我在发送时使用 ajax 编辑了我的问题并收到错误消息,标头上的身份验证部分已删除
    • 服务器是否还有其他消息,您可以使用 Chrome 开发工具 -> 打开网络选项卡查看响应消息。我认为这将与 CSRF 有关,但是,尝试一下并使用响应消息更新您的问题
    • 你是对的,它缺少 csrf 我完全忘记了。我将我的 ajax 集标头更改为 xhr.setRequestHeader('X-CSRFToken', '{{csrf_token}}');现在可以了,谢谢
    猜你喜欢
    • 2013-10-12
    • 1970-01-01
    • 2023-04-07
    • 2016-02-28
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多