如何在 django-rest-framework 中为 API 使用 TokenAuthentication
Posted
技术标签:
【中文标题】如何在 django-rest-framework 中为 API 使用 TokenAuthentication【英文标题】:How to use TokenAuthentication for API in django-rest-framework 【发布时间】:2013-07-07 18:26:11 【问题描述】:我有一个django项目,使用django-rest-framework来创建api。
想要使用基于令牌的身份验证系统,因此(放置、发布、删除)的 api 调用只会为授权用户执行。
我安装了“rest_framework.authtoken”并为每个用户创建了令牌。
所以,现在从 django.contrib.auth.backends 进行身份验证,它返回用户,以 auth_token 作为属性。 (登录成功时)。
现在我的问题是如何将带有 post 请求的令牌发送到我的 api 和 在 api 端如何验证令牌是否有效并且属于正确的用户?
应用程序 rest_framework.authtoken 中是否有任何方法可以验证给定用户及其令牌? 没找到this很有用!
更新(我所做的更改): 在我的 settings.py 中添加了这个:
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)
【问题讨论】:
基本上是重复的:***.com/questions/14838128/… 没有那个帖子只谈论创建令牌 - 我已经完成了那部分,现在想知道如何通过 http 请求传递令牌以及如何验证给定用户及其令牌。没有人谈论那部分。 它在 django-rest-framework 文档中有很好的记录。在客户端,您只需将标头添加到所有 HTTP 请求,django-rest-framework 在服务器端完成其余工作。如果提供了有效的令牌,您将拥有正确的用户 request.user 您需要对象级别的权限(经过身份验证的用户可以 POST/DELETE 自己的模型实例)还是只需要请求级别的权限(经过身份验证的用户可以执行任何 DELETE/POST)? 只是请求级别(经过身份验证的用户可以执行任何 DELETE/POST)并且我正在检查 request.user.is_staff 与否 【参考方案1】:“如何将令牌与 post 请求一起发送到我的 api”
来自文档...
对于客户端进行身份验证,令牌密钥应包含在 Authorization HTTP 标头中。键应以字符串文字“Token”为前缀,用空格分隔两个字符串。例如:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
“在api端如何验证令牌是否有效并且属于正确的用户?”
您无需执行任何操作,只需访问 request.user
即可返回经过身份验证的用户 - REST 框架将处理对任何不正确的身份验证返回“401 Unauthorized”响应。
【讨论】:
如果请求被重定向,请确保在初始请求和后续重定向请求中都发送令牌。 "只需访问 request.user 即可返回经过身份验证的用户"。文档说相同的“返回响应(内容)”,但我已经返回我的视图或我想在 api 页面中显示的任何内容。我怎样才能同时返回? 哇,没关系,我在现有的回报中附加了 'user': unicode(request.user) 和 'auth': unicode(request.auth) 并且现在可以使用。但是你我不得不重新粗略我的请求(auth_token),因为我在模板之间使用重定向。谢谢大家:)【参考方案2】:回答你问题的前半部分:
如何将带有 post 请求的令牌发送到我的 api
您可以使用 Python requests 库。对于django-rest-framework TokenAuthentication,token需要在header中传入,并以字符串Token
(see here)为前缀:
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))
【讨论】:
【参考方案3】:我终于有了用于令牌认证的 django“rest-auth”包。 如果这有帮助,在您成功登录并收到“auth_token”后,这里是对我有用的客户端 jQuery 代码:
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
);
【讨论】:
【参考方案4】:如果您使用的是 coreapi。添加您所做的授权
import coreapi
auth = coreapi.auth.TokenAuthentication(scheme='Token', token=token_key)
然后你可以做
client = coreapi.Client(auth=auth)
response = client.get(my_url)
【讨论】:
以上是关于如何在 django-rest-framework 中为 API 使用 TokenAuthentication的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 TemplateHTMLRenderer 在 Django-REST-Framework 中创建/放置?
如何使 DRF ( Django-REST-Framework) 令牌保持不变,使其在每次页面刷新后不会丢失?
django-rest-framework:如何序列化已经包含 JSON 的字段?
如何在 React 中显示来自 django-rest-framework 的错误消息