如何在Django中通过AJAX设置令牌身份验证以保护API url
我使用Django REST框架以JSON格式提供数据,并使用它们通过AJAX刷新页面。如何保护页面正在使用数据更新的URL,并且没有人可以访问API URL。url在html的AJAX中是可见的,因此可以访问它,但我想通过令牌或任何其他只有访问它的网站才具有的适当身份验证来阻止它 URL为“/api/item/”(请参见AJAX代码中的内容) 序列化程序.py如何在Django中通过AJAX设置令牌身份验证以保护API url,ajax,django,django-rest-framework,token,django-authentication,Ajax,Django,Django Rest Framework,Token,Django Authentication,我使用Django REST框架以JSON格式提供数据,并使用它们通过AJAX刷新页面。如何保护页面正在使用数据更新的URL,并且没有人可以访问API URL。url在html的AJAX中是可见的,因此可以访问它,但我想通过令牌或任何其他只有访问它的网站才具有的适当身份验证来阻止它 URL为“/api/item/”(请参见AJAX代码中的内容) 序列化程序.py from rest_framework import serializers from .models import Item c
from rest_framework import serializers
from .models import Item
class ItemModelSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = [
'title',
'value',
]
views.py(在API中)
url.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)
setInterval(函数(){
$.ajax({
方法:“获取”,
url:“/api/item/”,
成功:功能(数据){
$(“#items tbody”).empty();
$.each(数据、函数(键、值){
var itemKey=key;
var itemTitle=value.title;
var itemValue=value.value;
$(“#项目正文”)。追加(
“”+itemTitle+“”+itemValue”
)
})
},
错误:函数(数据){
console.log(“错误”)
console.log(数据)
}
})
}, 3000)
我不确定我是否正确理解了您的问题,我猜您是在问如何在AJAX中为Django中的API设置令牌。通常,我们使用共享令牌的概念。将有一个登录API,它将使用用户名/密码对用户进行身份验证。如果凭据正确,auth API将返回您可以使用的令牌并在AJAX请求中设置。使用该令牌进一步调用API进行身份验证
如果您直接想在不使用auth API的情况下调用API,则必须使用Django和AJAX之间共享的硬编码令牌,但是遵循这种做法是不安全的
在这里查找DRF身份验证我做了类似的事情: @Shwetabh Sharan您必须使用Django和AJAX之间共享的硬编码令牌 但是 @然而,Shwetabh Sharan说,遵循这种做法是不安全的 到目前为止,还没有人解决这个问题,即如何在Django、AJAX、JS中保护GET或POST请求,只有该网站可以使用它,没有其他网站可以使用它 他们总是推荐“JWT、令牌身份验证和会话身份验证”,等等。但所有这些解决方案都需要注册用户,如果我想保护搜索自动完成字段或前端上的任何公共内容,该怎么办 我已经创建了一个rest框架自定义权限,我使用django csrfmiddlewaretoken 它的行为与Django post表单相同,csrf令牌中间件发送一个使用
{%csrf_token%}
(使用令牌隐藏输入)隐藏的输入类型,但这种情况下只需要{csrf_token}
(令牌),Django将请求令牌与加密的cookie令牌进行比较
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)
}
});
});
“如果您直接想在没有auth API的情况下调用您的API,您将不得不使用Django和AJAX之间共享的硬编码令牌,但是遵循这种做法是不安全的。”-这正是我的重点-如何在Django、AJAX、JS中保护GET请求-只有该网站可以使用它-没有其他人可以使用它?
$('#search-snippet').keyup(function () {
$.ajax({
url:"{% url 'snippet-search-space:api' %}",
headers:{'api-csrftoken':'{{ csrf_token }}'},
success:function(data){
console.log(data)
}
});
});