[英]Secure REST API token in a JavaScript AJAX call
[英]How to set token authentication via AJAX in Django to secure the API url
我正在使用 Django REST 框架来获取 JSON 中的数据,并使用它们通过 AJAX 刷新页面。 如何保护正在使用数据更新页面的 URL,并且没有人可以访问 API url。 该 url 在 AJAX 中的 html 中可见,因此可以访问它,但我想通过令牌或任何其他正确的身份验证来阻止它,只有访问它才有网站。
URL 是“/api/item/”(参见 AJAX 代码)
序列化程序.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')
网址.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)
我不确定我是否正确理解您的问题,我猜您是在问如何在 AJAX 中为 Django 中的 API 设置令牌。 通常,我们使用共享令牌的概念。 将有一个登录 API,它将使用用户名/密码对用户进行身份验证。 如果凭据正确,auth API 将返回您可以在 AJAX 请求中使用和设置的令牌。 使用该令牌进一步调用您的 API 以进行身份验证。
如果您想直接调用没有身份验证 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 或 POST 请求,只有该网站可以使用它,其他人无法使用
他们总是推荐“JWT、令牌身份验证和会话身份验证”等。但是所有这些解决方案都需要用户注册,如果我想保护搜索自动完成字段或前端的任何公共内容会发生什么
我创建了一个休息框架自定义权限,我使用 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)
}
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.