Open alrhalford opened 5 years ago
In new project am also starting with djoser + knox.
Currently trying it with the following, and as brief djoser / knox code review showed - it should be ok.
The trick is not to use djoser urls, but instead use knox urls for token auth:
url.py
:
...
# Djoser auth urls
path("auth/", include("djoser.urls")),
# Replace djoser.urls.authtoken with knox urls for tokens
# overriding knox login view to allow initial login
path("auth/token/", include('myapp.api.urls')),
...
Social authentication so far returns jwt token for the user.
Afaics, social_auth returns already valid / created user, and djoser returns new / refreshed jwt token for him. In case of tokens - you can create other TokenStrategy classes (how social auth works in djoser may change in future).
TokenStrategy examples - from :
drf_token.py
:
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
class TokenStrategy:
@classmethod
def obtain(cls, user):
token, created = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
- using knox token - `knox_token.py`
from django.http import HttpRequest from knox.views import LoginView
class TokenStrategy:
@classmethod
def obtain(cls, user):
request = HttpRequest()
request.method = "POST"
request.user = user
request._force_auth_user = user
return LoginView.as_view()(request)
and specify required TokenStrategy in `settings.py`, i.e.:
DJOSER = { 'TOKEN_MODEL': 'knox.models.AuthToken', 'SOCIAL_AUTH_TOKEN_STRATEGY': 'myapp.api.knox_token.TokenStrategy', }
If you want to implement djoser social with knox nowadays, additionally to @rolep procedure, it is needed to save the retrieved token in a dictionary, that matches the ProviderAuthSerializer data. Therefore the Tokenstrategy must look like the following:
class TokenStrategy:
@classmethod
def obtain(cls, user):
request = HttpRequest()
request.method = "POST"
request.user = user
request._force_auth_user = user
val = LoginView.as_view()(request)
return {
'access': val.data['token'],
}
I'm trying to use djoser with token authentication, but using django-rest-knox tokens.
I have set the
TOKEN_MODEL
toknox.models.AuthToken
, and the rest framework'sDEFAULT_AUTHENTICATION_CLASSES
toknox.auth.TokenAuthentication
.I naïvely thought that this would be enough, but it seems that Djoser's inbuilt serializers (create token, and token), don't work properly with the knox tokens. I tried overriding them with custom serializers, but I didn't get anywhere (which is not to say it's not possible, just that I'm bad at this).
Settings:
Where users.serializers.TokenSerializer is:
This is only slightly modified from the original Djoser TokenSerializer. It was throwing an error that AuthToken objects did not have a
key
attribute. Knox tokens seem to call ittoken_key
, so I replaced the line:auth_token = serializers.CharField(source="key")
withauth_token = serializers.CharField(source="token_key")
Now, it doesn't throw an error, but it returns an empty token. Inspecting the actual db shows that it has saved a token with the correct user and creation time, but with 'null' for digest, salt, and token_key