问题
I'm trying to use djoser with token authentication, but using django-rest-knox tokens.
I have set the TOKEN_MODEL
to knox.models.AuthToken
, and the rest framework's DEFAULT_AUTHENTICATION_CLASSES
to knox.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).
It occurred to me that perhaps I should try using Knox's own login views... Is that possible, or can they not be mixed like that? (I'm mainly asking because I don't want to get it to 'work', but find that I've actually introduced a security hole in doing so).
Settings:
DJOSER = {
"TOKEN_MODEL": "knox.models.AuthToken",
"SERIALIZERS": {"token": "users.serializers.TokenSerializer"},
}
Where users.serializers.TokenSerializer is:
class TokenSerializer(serializers.ModelSerializer):
auth_token = serializers.CharField(source="token_key")
class Meta:
model = settings.TOKEN_MODEL
fields = ("auth_token",)
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 it token_key
, so I replaced the line:
auth_token = serializers.CharField(source="key")
with auth_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
回答1:
Yes, it is possible to mixin's Djoser
's and knox
's additional view point. For that we are going to create an app name auth
from where we are going to serve all authenticational related end-points. Now our project structure is like
MainProject
-auth
--__init__.py
--urls.py
-mainapp
....
Now in our auth
app's urls we are going to serve our necessary end-points for authentication. For that we are going to take help from Djoser
's urls link and Knox
's urls link
And our auth's urls.py will be like following
from django.conf.urls import url, include
from django.contrib.auth import get_user_model
from djoser import views as djsoer_views
from knox import views as knox_views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('users', djsoer_views.UserViewSet)
User = get_user_model()
djoser_urlpatterns = [
url(
r'^users/create/?$',
djsoer_views.UserCreateView.as_view(),
name='user-create'
),
url(
r'^users/delete/?$',
djsoer_views.UserDeleteView.as_view(),
name='user-delete'
),
url(
r'^users/activate/?$',
djsoer_views.ActivationView.as_view(),
name='user-activate'
),
url(
r'^{0}/?$'.format(User.USERNAME_FIELD),
djsoer_views.SetUsernameView.as_view(),
name='set_username'
),
url(r'^password/?$', djsoer_views.SetPasswordView.as_view(), name='set_password'),
url(
r'^password/reset/?$',
djsoer_views.PasswordResetView.as_view(),
name='password_reset'
),
url(
r'^password/reset/confirm/?$',
djsoer_views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm'
),
url(r'^$', djsoer_views.RootView.as_view(), name='root'),
url(r'^', include(router.urls)), ### If you want to add user view set
]
knox_urlpatterns = [
url(r'login/', knox_views.LoginView.as_view(), name='knox_login'),
url(r'logout/', knox_views.LogoutView.as_view(), name='knox_logout'),
url(r'logoutall/', knox_views.LogoutAllView.as_view(), name='knox_logoutall'),
]
urlpatterns = knox_urlpatterns + djoser_urlpatterns
Now we are going to add this urls under our main_app's urls
from django.urls import path
from django.conf import settings
auth_urls = include('auth.urls')
urlpatterns = [
path('api/auth/', auth_urls),
......
]
Now we are going to able to access every end-point like login as api/auth/login/
or user-create as api/auth/user/create/
etc.
来源:https://stackoverflow.com/questions/54960669/djoser-for-drf-with-knox-tokens