我在Django中使用基于令牌的身份验证,除了返回令牌之外还需要添加User对象。
如何覆盖此课程视图?我需要在哪里添加此类并进行更改?目前这可以在rest_framework包中找到,我不想修改库。
from rest_framework import parsers, renderers
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.serializers import AuthTokenSerializer
from rest_framework.response import Response
from rest_framework.views import APIView
class ObtainAuthToken(APIView):
throttle_classes = ()
permission_classes = ()
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)
renderer_classes = (renderers.JSONRenderer,)
serializer_class = AuthTokenSerializer
print "dasdsa"
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
obtain_auth_token = ObtainAuthToken.as_view()
答案 0 :(得分:3)
您应该将CustomClass
从AuthToken
,路线默认网址扩展到CustomClass
:
from rest_framework_jwt.views import ObtainJSONWebToken
class JSONWebTokenAPIOverride(ObtainJSONWebToken):
"""
Override JWT
"""
def post(self, request):
# Do whatever you want
然后在urls.py
:
url(
r'^api-auth$',
cache_page(0)(views.JSONWebTokenAPIOverride.as_view())
)
我希望它有所帮助
答案 1 :(得分:0)
我想覆盖一些默认的CRSF功能,并使用以下方法:
from rest_framework.authentication import SessionAuthentication
class SessionCsrfExemptAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
# Do not perform a csrf check
return False
然后在我的设置文件中,我通过以下方式引用它:
'DEFAULT_AUTHENTICATION_CLASSES': (
'myapp.utils.authenticate.SessionCsrfExemptAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
'rest_framework_social_oauth2.authentication.SocialAuthentication',
),
这允许我导入现有功能,覆盖它并在设置文件中引用它。我想你可以在这里使用类似的方法。
答案 2 :(得分:0)
我使用选项JWT_RESPONSE_PAYLOAD_HANDLER 在回复中,我包含令牌,到期时间戳和用户。
在 settings.py 中添加:
JWT_AUTH = {
...
'JWT_RESPONSE_PAYLOAD_HANDLER':'<app_name>.functions.custom_jwt_response',
}
然后在 functions.py 中添加以下内容
def custom_jwt_response(token, user=None, request=None):
import jwt
jwt = jwt.decode(token, verify=False)
return {
'token': token,
'token_exp': jwt['exp'],
'user': UserSerializer(user, context={'request': request}).data
}
答案 3 :(得分:0)
来自docs。
首先需要扩展ObtainAuthToken
类。
# views.py
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
'token': token.key,
'user_id': user.pk,
'email': user.email
})
然后将CustomAuthToken
类添加到您的urls.py
中,就像view
# urls.py
from django.urls import path
from . import views
urlpatterns += [
path(r'api-token-auth/', views.CustomAuthToken.as_view())
]
答案 4 :(得分:0)
这里的答案很好,但我认为它们没有充分利用继承。当我们继承一个类时,我们不应该只是尝试重新发明轮子,而应该使用super()关键字。这是我的代码示例,在该示例中,我想在执行身份验证请求之前将username参数转换为小写:
class GetAuthToken(ObtainAuthToken):
"""
Override Django's ObtainAuthToken to provide custom way of authenticating user for token
"""
def post(self, request, *args, **kwargs):
#-- turn username to lowercase
if ('username' in request.data):
request.data['username'] = request.data['username'].lower()
#-- perform normal function
return super().post(request, *args, **kwargs)