如何通过Django中的Ajax设置令牌身份验证以保护API URL



我正在使用django rest框架在JSON中可用数据,并使用它们通过AJAX刷新页面。如何使用数据更新该页面,没有人可以访问API URL。该URL在HTML的AJAX中可见,因此可以访问它,但我想通过令牌或任何其他仅访问其具有网站的正确身份验证来防止它。

URL是'/api/item/'(请参阅AJAX代码中的(

serializer.py

from rest_framework import serializers
from .models import Item
class ItemModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = [
            'title',
            'value',
        ]

views.py(在API中(

from rest_framework import generics
from .serializers import ItemModelSerializer
from .models import Item
class ItemListAPIView(generics.ListAPIView):
    serializer_class = ItemModelSerializer
    def get_queryset(self):
        return Item.objects.all().order_by('sort')

urls.py

urlpatterns = [
    #...urls...
    url(r'^api/item/', include('apps.item.api.urls', namespace='api-item')),
    url(r'^admin/', admin.site.urls),
]

模板-Ajax

setInterval(function() {
    $.ajax({
        method: "GET",
        url: "/api/item/",
        success: function(data) {
            $("#items tbody").empty();
            $.each(data, function (key, value) {                                      
                var itemKey = key;
                var itemTitle = value.title;  
                var itemValue = value.value;
                $("#items tbody").append(
                   "<tr><td class='left'>" + itemTitle + "</td><td>" + itemValue</td></tr>"
                )
            })
        },
        error: function(data) {
            console.log("error")
            console.log(data)
        }
    })
}, 3000)

我不确定我是否正确理解您的问题,我想您是在问如何在Django中为API设置一个令牌。通常,我们使用共享令牌的概念。将有一个登录API,它将用用户名/密码对用户进行身份验证。如果凭据正确,Auth API将返回您可以在AJAX请求中使用并设置的令牌。使用该令牌来进一步呼叫您的API进行身份验证。

如果您直接想在没有AUTH API的情况下直接调用API,则必须使用Django和Ajax之间共享的硬编码令牌,但是遵循此类实践是不安全的。

在这里查找DRF身份验证http://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication

我做了类似的事情:

@shwetabh sharan,您将不得不使用Django和Ajax之间共享的硬编码令牌

但是

@shwetabh Sharan说,但是,遵循此类实践

是不安全的

到目前为止,没有人解决此问题如何在django,ajax,js中获得get或张贴请求,只有该网站才能使用它

他们总是推荐" JWT,Token身份验证和会话身份验证"等。但是所有这些解决方案都需要注册的用户,如果我想保护搜索自动完整字段或前端上的任何东西,会发生什么情况

我创建了一个REST框架自定义许可,并且使用Djangocsrfmiddlewaretoken

它的行为与django帖子表格相同,csrf代币中间件发送隐藏在 {% csrf_token %}的输入类型(与令牌隐藏的输入(,但是这种情况只需要 {{ csrf_token }}(token(,django将请求与cookie socken的请求与cookie notken进行比较被加密

permission.py
    from django.middleware.csrf import _compare_salted_tokens, rotate_token
    from rest_framework.permissions import BasePermission

    class HasCsrfTokenValid(BasePermission):
        def has_permission(self, request, view):
            token_valid = False
            try:
                csrf_token = request.headers.get("api-csrftoken")
                csrf_cookie = request.META.get("CSRF_COOKIE")
                """
                Check if both alphanumerics(strings) values are differents to prevent 
                a malicious user get the csrf cookie and send it from the ajax.
                """
                if csrf_token == csrf_cookie:
                    rotate_token(request)
                    return False
                token_valid =  _compare_salted_tokens(csrf_token, csrf_cookie)
            except ValueError: # if csrf_token & csrf_cookie are not a valid alphanumeric
                return False
            return token_valid

将权限类添加到API视图

views.py
class SnippetSearchAPI(generics.ListAPIView):
    model = Snippet
    serializer_class = SnippetSearcSerializer
    permission_classes = [HasCsrfTokenValid,]
    queryset = Snippet.objects.all()

ajax请求:

$('#search-snippet').keyup(function () {
    $.ajax({
       url:"{% url 'snippet-search-space:api' %}",
       headers:{'api-csrftoken':'{{ csrf_token }}'},
       success:function(data){
         console.log(data)
       }
   });
 });

最新更新