我在Django中设置了rest api,并使用React Native与之连接。我已经注册了用户,可以生成令牌,但无法在GET请求的头部传递令牌。我的代码如下:
try{
let response = await fetch("http://127.0.0.1:8000/fishes/auth/",
{
method: 'GET',
headers: {
// 'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': ' Token '+accessToken,
}});
let res = await response.text();
}}
我一直在关注这个链接http://cheng.logdown.com/posts/2015/10/27/how-to-use-django-rest-frameworks-token-based-authentication并且已经验证了来自rest api的响应是正确的。
然而,在使用native react的手机上,我在控制台中收到以下错误:
TypeError: Network request failed
at XMLHttpRequest.xhr.onerror (fetch.js:441)
at XMLHttpRequest.dispatchEvent (event-target.js:172)
at XMLHttpRequest.setReadyState (XMLHttpRequest.js:542)
我在GET代码中做错了什么?
Okay 401状态代码,表示未授权。对于Django Rest Framework,您必须将访问令牌作为所有API请求的头的一部分传入。
标题格式将为
Key : Authorization
Value: Token <token>
你可以在这里看到更多http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
我认为您需要更改
"内容类型"到"内容类型">
在小写上
请参阅此答案。
同源策略限制了网页可以发送到其他来源的资源的请求类型。
在无cors模式下,浏览器仅限于发送"简单"请求——那些只包含安全列出的方法和安全列出的头的请求。
要发送具有Authorization和X-My-Custom-Header等标头的跨来源请求,您必须放弃无cors模式并支持飞行前请求(OPTIONS)。
"简单"请求和"非简单"请求之间的区别是出于历史原因。网页总是可以通过各种方式(如创建和提交表单)执行一些跨来源请求,因此,当Web浏览器引入了发送跨来源请求的原则性方式(跨来源资源共享或CORS)时,决定这种"简单"请求可以不受飞行前选项检查的约束。
正如OP.所说,我通过处理飞行前请求来解决这个问题
以前,在我的中间件中,我过滤掉了不包括身份验证令牌的请求,如果它们试图访问私有数据,则返回403。现在,我检查飞行前,并发送允许这些类型的头的响应。这样,当下面的请求(get、post等)到来时,它将具有所需的头,并且我可以按照最初的意图使用我的中间件。
这是我的中间件:
class ValidateInflight(MiddlewareMixin):
def process_view(self, request, view_func, view_args, view_kwargs):
assert hasattr(request, 'user')
path = request.path.lstrip('/')
if path not in EXEMPT_URLS:
logger.info(path)
header_token = request.META.get('HTTP_AUTHORIZATION', None)
if header_token is not None:
try:
token = header_token
token_obj = Token.objects.get(token=token)
request.user = token_obj.user
except Token.DoesNotExist:
return HttpResponse(status=403)
elif request.method == 'OPTIONS':
pass
else:
return HttpResponse(status=403)
这是我处理的选项
class BaseView(View):
def options(self, request, *args, **kwargs):
res = super().options(request, *args, **kwargs)
res['Access-Control-Allow-Origin'] = '*'
res['Access-Control-Allow-Headers'] = '*'
return res