Moved jwt auth class to separate file to avoid hard dependency.

This commit is contained in:
Noam 2020-06-23 20:28:18 +03:00
parent 8568c8221b
commit b2c06fa18a
6 changed files with 48 additions and 43 deletions

View File

@ -123,7 +123,7 @@ REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ( 'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.TokenAuthentication',
'dj_rest_auth.utils.JWTCookieAuthentication' 'dj_rest_auth.jwt_auth.JWTCookieAuthentication'
), ),
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema' 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
} }

27
dj_rest_auth/jwt_auth.py Normal file
View File

@ -0,0 +1,27 @@
from django.conf import settings
from rest_framework_simplejwt.authentication import JWTAuthentication
class JWTCookieAuthentication(JWTAuthentication):
"""
An authentication plugin that hopefully authenticates requests through a JSON web
token provided in a request cookie (and through the header as normal, with a
preference to the header).
"""
def authenticate(self, request):
cookie_name = getattr(settings, 'JWT_AUTH_COOKIE', None)
header = self.get_header(request)
if header is None:
if cookie_name:
raw_token = request.COOKIES.get(cookie_name)
else:
return None
else:
raw_token = self.get_raw_token(header)
if raw_token is None:
return None
validated_token = self.get_validated_token(raw_token)
return self.get_user(validated_token), validated_token

View File

@ -68,7 +68,7 @@ TEMPLATES = [
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ( 'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.SessionAuthentication',
'dj_rest_auth.utils.JWTCookieAuthentication', 'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
) )
} }

View File

@ -563,7 +563,7 @@ class APIBasicTests(TestsMixin, TestCase):
@override_settings(JWT_AUTH_COOKIE='jwt-auth') @override_settings(JWT_AUTH_COOKIE='jwt-auth')
@override_settings(REST_FRAMEWORK=dict( @override_settings(REST_FRAMEWORK=dict(
DEFAULT_AUTHENTICATION_CLASSES=[ DEFAULT_AUTHENTICATION_CLASSES=[
'dj_rest_auth.utils.JWTCookieAuthentication' 'dj_rest_auth.jwt_auth.JWTCookieAuthentication'
] ]
)) ))
@override_settings(REST_SESSION_LOGIN=False) @override_settings(REST_SESSION_LOGIN=False)
@ -624,7 +624,7 @@ class APIBasicTests(TestsMixin, TestCase):
@override_settings(JWT_AUTH_COOKIE=None) @override_settings(JWT_AUTH_COOKIE=None)
@override_settings(REST_FRAMEWORK=dict( @override_settings(REST_FRAMEWORK=dict(
DEFAULT_AUTHENTICATION_CLASSES=[ DEFAULT_AUTHENTICATION_CLASSES=[
'dj_rest_auth.utils.JWTCookieAuthentication' 'dj_rest_auth.jwt_auth.JWTCookieAuthentication'
] ]
)) ))
@override_settings(REST_SESSION_LOGIN=False) @override_settings(REST_SESSION_LOGIN=False)
@ -649,7 +649,7 @@ class APIBasicTests(TestsMixin, TestCase):
@override_settings(JWT_AUTH_COOKIE='jwt-auth') @override_settings(JWT_AUTH_COOKIE='jwt-auth')
@override_settings(REST_FRAMEWORK=dict( @override_settings(REST_FRAMEWORK=dict(
DEFAULT_AUTHENTICATION_CLASSES=[ DEFAULT_AUTHENTICATION_CLASSES=[
'dj_rest_auth.utils.JWTCookieAuthentication' 'dj_rest_auth.jwt_auth.JWTCookieAuthentication'
] ]
)) ))
@override_settings(REST_SESSION_LOGIN=False) @override_settings(REST_SESSION_LOGIN=False)

View File

@ -1,5 +1,7 @@
from importlib import import_module from importlib import import_module
from django.conf import settings
def import_callable(path_or_callable): def import_callable(path_or_callable):
if hasattr(path_or_callable, '__call__'): if hasattr(path_or_callable, '__call__'):
@ -15,38 +17,14 @@ def default_create_token(token_model, user, serializer):
return token return token
try: def jwt_encode(user):
from django.conf import settings
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
TOPS = import_callable(getattr(settings, 'JWT_TOKEN_CLAIMS_SERIALIZER', TokenObtainPairSerializer))
refresh = TOPS.get_token(user)
return refresh.access_token, refresh
def jwt_encode(user):
TOPS = import_callable(getattr(settings, 'JWT_TOKEN_CLAIMS_SERIALIZER', TokenObtainPairSerializer))
refresh = TOPS.get_token(user)
return refresh.access_token, refresh
class JWTCookieAuthentication(JWTAuthentication):
"""
An authentication plugin that hopefully authenticates requests through a JSON web
token provided in a request cookie (and through the header as normal, with a
preference to the header).
"""
def authenticate(self, request):
cookie_name = getattr(settings, 'JWT_AUTH_COOKIE', None)
header = self.get_header(request)
if header is None:
if cookie_name:
raw_token = request.COOKIES.get(cookie_name)
else:
return None
else:
raw_token = self.get_raw_token(header)
if raw_token is None:
return None
validated_token = self.get_validated_token(raw_token)
return self.get_user(validated_token), validated_token
try:
from .jwt_auth import JWTCookieAuthentication
except ImportError: except ImportError:
raise ImportError("rest-framework-simplejwt needs to be installed") pass

View File

@ -35,9 +35,9 @@ Installation
.. code-block:: python .. code-block:: python
python manage.py migrate python manage.py migrate
You're good to go now! You're good to go now!
@ -59,7 +59,7 @@ Registration (optional)
'allauth.account', 'allauth.account',
'dj_rest_auth.registration', 'dj_rest_auth.registration',
) )
SITE_ID = 1 SITE_ID = 1
3. Add dj_rest_auth.registration urls: 3. Add dj_rest_auth.registration urls:
@ -76,7 +76,7 @@ Registration (optional)
Social Authentication (optional) Social Authentication (optional)
-------------------------------- --------------------------------
Using ``django-allauth``, ``dj-rest-auth`` provides helpful class for creating social media authentication view. Using ``django-allauth``, ``dj-rest-auth`` provides helpful class for creating social media authentication view.
.. note:: Points 1 and 2 are related to ``django-allauth`` configuration, so if you have already configured social authentication, then please go to step 3. See ``django-allauth`` documentation for more details. .. note:: Points 1 and 2 are related to ``django-allauth`` configuration, so if you have already configured social authentication, then please go to step 3. See ``django-allauth`` documentation for more details.
@ -223,7 +223,7 @@ In urls.py:
You can also use the following views to check all social accounts attached to the current authenticated user and disconnect selected social accounts: You can also use the following views to check all social accounts attached to the current authenticated user and disconnect selected social accounts:
.. code-block:: python .. code-block:: python
from dj_rest_auth.registration.views import ( from dj_rest_auth.registration.views import (
SocialAccountListView, SocialAccountDisconnectView SocialAccountListView, SocialAccountDisconnectView
) )
@ -259,7 +259,7 @@ By default ``dj-rest-auth`` uses Django's Token-based authentication. If you wan
... ...
'DEFAULT_AUTHENTICATION_CLASSES': ( 'DEFAULT_AUTHENTICATION_CLASSES': (
... ...
'dj_rest_auth.utils.JWTCookieAuthentication', 'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
) )
... ...
} }