我正在使用Django 2.x和Django REST框架。
我正在使用django-oauth-toolkit
启用OAuth2
身份验证,使用django-rest-auth
进行登录,使用django-allauth
进行用户注册。
当用户成功注册后,我想在响应中生成访问令牌。为此,我使用了自定义注册视图。
为此,我创建了一个函数实用程序,如
def generate_token(request, user):
# Get OAuth application to use
application_: Application = Application.objects.filter(
client_type=Application.CLIENT_CONFIDENTIAL,
authorization_grant_type=Application.GRANT_PASSWORD
).first()
if not application_:
raise Exception('No OAuth2 Application is setup')
auth_data = {
'username': user.username,
'password': password,
'grant_type': 'password',
'client_id': application_.client_id,
'client_secret': application_.client_secret
}
if request.data:
mutable = request.data._mutable
request.data._mutable = True
request.data.update(auth_data)
request.data._mutable = mutable
if request.POST:
mutable = request.POST._mutable
request.POST._mutable = True
request.POST.update(auth_data)
request.POST._mutable = mutable
return TokenView().create_token_response(request=request)
当端点被 Postman 击中时,它可以正常工作,并且request.data
具有_mutable
属性。
但是当被Angular应用程序击中时,它会给出错误
'dict' object has no attribute '_mutable'
,错误指向mutable = request.data._mutable
为什么某些请求中缺少_mutable
?
编辑2:请求标头
邮递员发送的请求标头是
Content-Type:"application/json"
Accept:"application/json, text/plain, /"
User-Agent:"PostmanRuntime/7.15.2"
Cache-Control:"no-cache"
Postman-Token:"b4461728-a6a9-48da-a4fa-3894920b5484"
Host:"api.staging.scanova.io"
Cookie:"messages="660481c3ce8c48b1884641ffdec0a3f701cdc9cf$..."; csrftoken=tNa6o6RDkEUTBti1cDJCvgV5oLG84qczgADeDfSY7hROsLP6cmhIgQKaamPQU7Xy; sessionid=r0l8kh58n8i14quyemj60ur6i59uhy1i"
Accept-Encoding:"gzip, deflate"
Content-Length:635
Connection:"keep-alive"
来自Angular的请求标头是
Accept: application/json, text/plain, */*
Authorization: false false
Content-Type: application/json
Origin: https://localhost:4200
Referer: https://localhost:4200/auth/register
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36
编辑3:请求类型
从端点调用的主视图是CreateAPIView
。从此视图调用generate_token
,该视图使用TokenView
生成访问令牌。 TokenView
使用Django的通用View
。
答案 0 :(得分:0)
对于后代(即使问题相当古老):
django / DRF似乎以足以引起问题的不同方式对待multipart/form-data
和application/json
内容类型。
因此,即使使用相同的终结点(视图集),并且取决于表单是以分段形式发送还是以app / json形式发送,request.data
也会是另一个对象。
在一种情况下,它将是“正常”命令,而在另一种情况下,它将是QueryDict
类型。因此,为了使用开/关_mutable
,需要进行与此类似的附加检查:
...
# one can also use:
# if 'multipart/form-data' in request.META.get('CONTENT_TYPE'):
# instead of the condition below
if isinstance(request.data, QueryDict):
auth_data = json.dumps(auth_data) # <----- QueryDict expects string values
request.POST._mutable = True # <----- mutable needs to be modified on POST and not on data
request.data.update(auth_data)
request.POST._mutable = False
...
答案 1 :(得分:0)
我使用了(request.POST._mutable = True),这种方式对我不起作用。 然后我将request.POST复制到一个新变量中,并在整个代码中使用了新变量,这种方式可以正常工作