[英]Using external API for token based authentication in Django (DRF)
My API accepts a jwt-token that I can pass to an external endpoint which will return 401 if invalid/expired or user information if still valid.我的 API 接受一个 jwt 令牌,我可以将其传递给外部端点,如果无效/过期,则返回 401,如果仍然有效,则返回用户信息。 Based on this I will either return 401 or filtered data belonging to the user.
基于此,我将返回 401 或属于用户的过滤数据。 Also, POST request's need to involve writing who this resource belongs to for the GET to work.
此外,POST 请求需要涉及写入此资源属于谁以使 GET 工作。 I tried to do this by overriding the get_queryset and perform_create methods.
我试图通过覆盖 get_queryset 和 perform_create 方法来做到这一点。
My viewset looks something like this:我的视图集看起来像这样:
class ReportViewSet(AuthorizedUserBasedFilteredViewset):
queryset = Report.objects.all()
serializer_class = ReportSerializer
def perform_create(self, serializer):
try:
username = self.get_authorized_user()['user']['username']
except Exception as e:
return Response({'error': 'Token does not exist'}, status=HTTP_401_UNAUTHORIZED)
serializer.save(creatd_by=username)
def get_queryset(self):
try:
username = self.get_authorized_user()['user']['username']
except Exception as e:
return Response({'error': 'Token does not exist'}, status=HTTP_401_UNAUTHORIZED)
return Report.objects.filter(created_by=username)
This doesn't work because get_queryset expects a queryset as response.这不起作用,因为 get_queryset 需要一个查询集作为响应。
Instead of代替
return Response({'error': 'Token does not exist'}, status=HTTP_401_UNAUTHORIZED)
use this用这个
raise NotAuthenticated(detail='Token does not exist')
Hope above line has addressed your 1st question.希望以上行已经解决了您的第一个问题。
For 2nd question.对于第二个问题。 You can extend
TokenAuthentication
and then implement def authenticate_credentials(self, key):
method.您可以扩展
TokenAuthentication
,然后实现def authenticate_credentials(self, key):
方法。 It is not a good idea to call external API to fetch user each time .每次都调用外部 API 来获取用户不是一个好主意。 Rather you should get JTW token one time from external source then pass JWT token in header like
Authorization : Bearer cn389ncoiwuencr
for each API call.相反,您应该从外部源获取一次 JTW 令牌,然后在像
Authorization : Bearer cn389ncoiwuencr
这样的标头中为每个 API 调用传递 JWT 令牌。 Then you should decode JWT token in current system.然后你应该在当前系统中解码 JWT 令牌。
from rest_framework.authentication import TokenAuthentication
from django.contrib.auth import get_user_model
class CustomTokenAuthentication(TokenAuthentication):
keyword = 'Bearer' # token type
def authenticate_credentials(self, key):
#decode JWT.
username = get_username()
User = get_user_model()
user = User(username=username)
return user, key
Finally, add this class at settings.py file.最后,在 settings.py 文件中添加这个类。
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'path.of.CustomTokenAuthentication',
)
}
That will apply to all of your views.这将适用于您的所有观点。 or you can apply view specific auth class.
或者您可以应用查看特定的身份验证类。
class Sample(ViewSet):
authentication_classes = (CustomTokenAuthentication,)
From now you can access user by request.user
at views or viewset.从现在开始,您可以通过
request.user
在视图或视图集访问用户。 That's it.就是这样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.