如何在Django REST框架中使用TokenAuthentication进行API身份验证

35

我有一个Django项目,使用Django-rest-framework创建API。

想要使用基于令牌的身份验证系统,以便只有经过授权的用户才能执行(put,post,delete)的API调用。

我安装了'rest_framework.authtoken'并为每个用户创建了令牌。

因此,现在从django.contrib.auth.backends验证,它返回带有auth_token属性的用户(当成功登录时)。

现在我的问题是如何在post请求中发送令牌到我的API,以及在API方面如何验证令牌是否有效并属于正确的用户?

在rest_framework.authtoken应用程序中是否有任何方法可以验证给定的用户及其令牌?我没有发现这个页面特别有用!

更新(我所做的更改):

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    )
}

我在头部中也发送了令牌,但它仍然不起作用:

if new_form.is_valid:
    payload= {"createNewUser":
              { "users": request.POST["newusers"],
                "email": request.POST["newemail"]
                }
              }

    headers =  {'content-type' : 'application/json', 
                'Authorization': 'Token 6b929e47f278068fe6ac8235cda09707a3aa7ba1'}

    r = requests.post('http://localhost:8000/api/v1.0/user_list',
                      data=json.dumps(payload),
                      headers=headers, verify=False)

基本上是一个重复的问题:https://dev59.com/dGUq5IYBdhLWcg3wC8Hx - jdero
nop这篇文章只是讲如何创建令牌 - 我已经完成了这一部分,现在想知道如何通过HTTP请求传递令牌以及如何验证给定用户和其令牌。没有人谈论过那部分。 - Peter
1
在Django Rest Framework文档中有非常详细的说明。在客户端,您只需将标头添加到所有HTTP请求中,Django Rest Framework会在服务器端完成其余工作。如果提供了有效的令牌,则请求用户将是正确的用户。 - jasisz
你需要对象级别的权限(已认证用户可以POST/DELETE他们自己的模型实例)还是只需要请求级别的权限(已认证用户可以执行任何DELETE/POST)? - will-hart
仅请求级别(已验证的用户可以执行任何DELETE / POST),我正在检查request.user.is_staff是否为真。 - Peter
4个回答

36

我该如何在Post请求中发送令牌到我的API?

来自文档...

为了进行身份验证,客户端应将令牌键包含在Authorization HTTP标头中。该键应以字符串文字“Token”为前缀,并在两个字符串之间加上空格。例如:

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
你不需要做什么,只需访问request.user来返回认证的用户 - REST框架将处理返回任何错误认证的 '401 Unauthorized' 响应。

2
如果请求被重定向,请确保令牌在初始请求和后续重定向请求中都被发送。 - Tom Christie
只需访问request.user即可返回经过身份验证的用户。文档中说相同的“return Response(content)”,但我已经在返回我的视图或任何我想要在API页面显示的内容了。我如何同时返回两者? - Peter
哇,算了吧。我在现有的返回值中添加了“user”:unicode(request.user)和“auth”:unicode(request.auth),现在它可以工作了。但是,我不得不重新处理我的请求(auth_token),因为我在模板之间使用了重定向。谢谢大家 :) - Peter

4
回答你问题的前半部分:

如何通过post请求向我的api发送令牌

你可以使用Python的requests库。对于django-rest-framework TokenAuthentication,令牌需要作为头信息传递,并在前面加上"Token"字符串(见此处):
import requests
mytoken = "4652400bd6c3df8eaa360d26560ab59c81e0a164"
myurl = "http://localhost:8000/api/user_list"

# A get request (json example):
response = requests.get(myurl, headers={'Authorization': 'Token {}'.format(mytoken)})
data = response.json()

# A post request:
data = { < your post data >}
requests.post(myurl, data=data, headers={'Authorization': 'Token {}'.format(mytoken)})

1

我终于让Django的"rest-auth"包正常工作了,用于令牌身份验证。 如果有帮助,这是客户端jQuery代码,对我有效,在您成功登录并接收到“auth_token”后:

var user_url = {API URL}/rest-auth/login
var auth_headers = {
  Authorization: 'Token ' + auth_token
}
var user_ajax_obj = {
  url : user_url,
  dataType : 'json',
  headers: auth_headers,
  success : function(data) {
    console.log('authorized user returned');
  },
  error: function(XMLHttpRequest, textStatus, errorThrown) {
    console.log('error returned from ' + user_url);
  }
};
$.ajax(
  user_ajax_obj
);

0
如果您正在使用 coreapi ,要添加授权,请执行以下操作: import coreapi auth = coreapi.auth.TokenAuthentication(scheme='Token', token=token_key) 然后,您可以执行: client = coreapi.Client(auth=auth) response = client.get(my_url)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接