how to turn jwt settings into simplejwt settings? - django-rest-framework

Here is my problem. I have a project that used rest_framework_JWT like this
JWT_AUTH = {
"JWT_VERIFY": True,
"JWT_VERIFY_EXPIRATION": True,
"JWT_EXPIRATION_DELTA": datetime.timedelta(days=30),
"JWT_AUTH_HEADER_PREFIX": "Bearer",
"JWT_AUTH_COOKIE": "x-access-token",
}
but now i want to change from JWT to rest_framework_simpleJWT, what is the corresponding fields should i change to in simplejwt? Is this right?
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=5),
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_X_ACCESS_TOKEN',
}

I think you need to add and change the settings in the INSTALLED_APPS and REST_FRAMEWORK.DEFAULT_AUTHENTICATION_CLASSES.
In settings.py file,
INSTALLED_APPS = [
...
'rest_framework_simplejwt'
]
...
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': {
'rest_framework_simplejwt.authentication.JWTAuthentication'
}
...
}

Here is the sample configuration settings you can set:
# Django project settings.py
from datetime import timedelta
...
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': False,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'JWK_URL': None,
'LEEWAY': 0,
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
Link to its documentation is here: documentation
Also, this is a boiler plate code that you can also plug and play in your project for Django authentication with simplejwt.
You can simply clone it and add above configuration in settings.py file there.
Boiler plate code for django simplejwt authentication

Related

How to differentiate my views in DRF swagger (yasg)?

I have an api made with djangorestframework and I want to add a swagger. It works well. In my api I have some views that require authentication with Basic or JWT so I set this up in my settings. The problem is that in my swagger gui I do not manage to tell which view is not requiring authentication. Do you know how to do that.
#api/urls.py
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="Snippets API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact#snippets.local"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)
urlpatterns = [
path('mesures/', views.get_all),
path('mesure-add/', views.add_mesure),
path('token/', TokenObtainPairView.as_view(), name='obtain_tokens'),
path('token/refresh/', TokenRefreshView.as_view(), name='refresh_token'),
path('api-auth/', include('rest_framework.urls')),
path('register/', views.register_user),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]
In my settings.py
# in my settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(days=int(os.getenv("TOKEN_DAYS_LIFE"))),
}
SWAGGER_SETTINGS = {
'SECURITY_DEFINITIONS': {
'Basic': {
'type': 'basic'
},
'Bearer': {
'type': 'apiKey',
'name': 'Authorization',
'in': 'header'
}
}
}
In my views.py
#views.py
#swagger_auto_schema(methods=['post'], request_body=MesureSerializer)
#api_view(['POST'])
#permission_classes([IsAuthenticated])
def add_mesure(request):
serializer = MesureSerializer(data=request.data, context={'request':request})
# this is to provide the user automatically from token auth
# no need to provide it from the post request
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer._errors)
#swagger_auto_schema(methods=['post'], request_body=UserSerializer)
#api_view(['POST'])
def register_user(request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
as you can see my view register_user should not show a authentication in my swagger but this is not the case.
It is ok, I just needed to use the security=[] in #swagger_auto_schema for the specific view I want to tell there is no authentication required.
#swagger_auto_schema(methods=['post'], request_body=UserSerializer, security=[])

I can't see DRF api confirm browser

i want to see
But my browser is
I checked the api operation through postman.
i have no idea what is the problem..
I don't think there's a problem with the code
This is my code
project folder urls.py
url(r'^', include('django.contrib.auth.urls')),
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
url(r'^account/', include('allauth.urls')),
url(r'^accounts-rest/registration/account-confirm-email/(?P<key>.+)/$',
confirm_email, name='account_confirm_email'),
settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
# 'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
),
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
],
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
],
}
REST_AUTH_SERIALIZERS = {
'USER_DETAILS_SERIALIZER': 'accounts.serializers.UserSerializer',
}
Any hint would be very very very appreciated :)
Add rest_framework.renderers.BrowsableAPIRenderer to default renderer classes of the REST_FRAMEWORK settings.
...
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
...

Problem with the error * A server error occurred. Please contact the administrator * django rest framework

I am trying to test some basic backed fonctionnalities but I seem to have this error A server error occurred. Please contact the administrator while trying to connect to the localhost http://127.0.0.1:8000 or http://127.0.0.1:8000/sise/.
At first I had this error showing django.core.exceptions.ImproperlyConfigured: The included URLconf 'Dashboard_sise.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import. but After I commented this line in the settings file ROOT_URLCONF = 'Dashboard_sise.urls' the error changed into A server error occurred. Please contact the administrator.
Can anyone please help me figure this problem out, I already tried changing the urlpatterns in the urls.py files but it didn't work, I also tried manipulating the MIDDLEWARE section in the settings file but nothing changed.
This is the Dashboard_sise.urls code
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.sites.urls),
path('sise/', include('Dashboard.urls')),
]
This is the Dashboard.urls code
from rest_framework.routers import DefaultRouter
from Dashboard.views import *
router = DefaultRouter()
router.register(r'accee', AcceeViewSet, basename='accee')
router.register(r'rapport', RapportViewSet, basename='rapport')
router.register(r'prise_fonction', PointageUtilisateurViewSet, basename='prise_fonction')
urlPatterns = router.urls
and finally the settings file
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '+f-#$j*(-8^*7ijk#6_hpki#)am4e%na6ttp)54#-ddcs0#fgy'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
PREPEND_WWW = False
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'Dashboard',
'frontend'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'Dashboard_sise.wsgi.application'
'''ROOT_URLCONF = 'Dashboard_sise.urls'''
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'MainCourante',
'USER': 'postgres',
'PASSWORD': 'root',
'HOST': 'localhost',
'PORT': '5432',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
APPEND_SLASH = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
'''REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.authentification.BasicAuthentification'
'rest_framework.authentification.SessionAuthentification'
# 'rest_framework.permissions.IsAuthentificated'
# 'rest_framework.permissions.AllowAny'
)
}'''
CORS_ORIGIN_ALLOW_ALL = True # If this is used then `CORS_ORIGIN_WHITELIST` will not have any effect
Thank you in adavance
I will answer this in case someone faced the same bug. I had a problem with the database structure .. The models implemented in the models.py file and the database created didn't match so it kept showing me this error ... once I fixed the models.py file it all worked well
Maybe this was the cause.
urlPatterns = router.urls
its usually urlpatterns.

Set expiration time to sample django jwt token

I am trying to create a manual token and I would like to add expiration time.from here =>Documentation
here=>
from rest_framework_simplejwt.tokens import RefreshToken
refresh = RefreshToken.for_user(user)
refresh.set_exp(lifetime=datetime.timedelta(days=10))
# refresh.lifetime = datetime.timedelta(days=10)
return Response ({
'access': str(refresh.access_token),'refresh':str(refresh),"status":"success"
})
here is setting.py=>
JWT_AUTH = {
# how long the original token is valid for
'ACCESS_TOKEN_LIFETIME': datetime.timedelta(days=2),
# allow refreshing of tokens
'JWT_ALLOW_REFRESH': True,
# this is the maximum time AFTER the token was issued that
# it can be refreshed. exprired tokens can't be refreshed.
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=7),
}
but why this access token is expired after 5 min even I added 10 days? How can I add expiration time?
This method is created for authenticating with email and password. because default authentication is using user id and password. Is there any way to authenticate with email and password in drf sample jwt?
Hey you can decide to use django-rest-framework-simplejwt library or rest_framework_jwt
For django-rest-framework-simplejwt use this way in your settings.py
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(days=10),
'REFRESH_TOKEN_LIFETIME': timedelta(days=20),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM': 'HS256',
'SIGNING_KEY': settings.SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(days=10),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=20),
}
For rest_framework_jwt use this way in your settings.py
JWT_AUTH = {
'JWT_ENCODE_HANDLER':
'rest_framework_jwt.utils.jwt_encode_handler',
'JWT_DECODE_HANDLER':
'rest_framework_jwt.utils.jwt_decode_handler',
'JWT_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_payload_handler',
'JWT_PAYLOAD_GET_USER_ID_HANDLER':
'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler',
'JWT_RESPONSE_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_response_payload_handler',
'JWT_SECRET_KEY': settings.SECRET_KEY,
'JWT_GET_USER_SECRET_KEY': None,
'JWT_PUBLIC_KEY': None,
'JWT_PRIVATE_KEY': None,
'JWT_ALGORITHM': 'HS256',
'JWT_VERIFY': True,
'JWT_VERIFY_EXPIRATION': True,
'JWT_LEEWAY': 0,
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=10),
'JWT_AUDIENCE': None,
'JWT_ISSUER': None,
'JWT_ALLOW_REFRESH': False,
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=30),
'JWT_AUTH_HEADER_PREFIX': 'JWT',
'JWT_AUTH_COOKIE': None,
}
you have an error because you are updating the refresh time, you have to access the access_token
def get_tokens_for_user(user):
refresh = RefreshToken.for_user(user)
access_token = refresh.access_token
access_token.set_exp(lifetime=timedelta(days=10))
return {
'refresh': str(refresh),
'access': str(access_token),
}
You're using the lib Simple JWT, according to the documentation, in the settings, you have to use 'SIMPLE_JWT' instead of 'JWT_AUTH'.

raven - sentry + django = No servers configured, and sentry not installed. Cannot send message

I have a sentry server that works ok.
raven test <dnstoserver> -> Sending a test message... success!
I have a dev machine with django 1.3 and raven 1.93.
In the django project I have this:
setting.py:
SENTRY_KEY=<secretkey>
SENTRY_DNS=<dnstoserver>
INSTALLED_APPS = (
'bar',
'foo',
'raven.contrib.django',
)
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'root': {
'level': 'WARNING',
'handlers': ['sentry'],
},
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
},
'handlers': {
'sentry': {
'level': 'ERROR',
'class': 'raven.contrib.django.handlers.SentryHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
},
'loggers': {
'django.db.backends': {
'level': 'ERROR',
'handlers': ['console'],
'propagate': False,
},
'raven': {
'level': 'DEBUG',
'handlers': ['console', 'sentry'],
'propagate': False,
},
},
}
Mind the absence of 'sentry' in the installed_apps. This is intentionally, since sentry is the server and should not be on a client!
views.py (in a view):
import logging
logger = logging.getLogger("raven")
logger.error("test")
When I run the view I get on the console:
No servers configured, and sentry not installed. Cannot send message
Why, and how to fix?
Were you really setting SENTRY_DNS or SENTRY_DSN?
When you set SENTRY_DSN the instantiation of the major config variables happens automatically (including SENTRY_SERVERS, SENTRY_PUBLIC_KEY, SENTRY_SECRET_KEY, and SENTRY_PROJECT)
The problem was in the construction of the raven DjangoClient. It did not get passed any servers, and couldn't find sentry config to steal that config from.
I added in the settings.py:
SENTRY_SERVERS=<dnstoserver>
Console now outputs this every time raven is called:
INFO 2012-06-21 05:33:19,831 base 4323 140735075462336 Configuring Raven for host: <dnstoserver>
But it works like a charm! Messages in sentry...
BTW. for all the undocumented settings take a look in raven.contrib.django.models.get_client()
I suggest to use:
SENTRY_DSN = 'http://user:password#<domain>:<port>/<project_id>'
And in APPS_INSTALLED add:
'raven.contrib.django.raven_compat'
Also take a look at this guide:
http://code.fetzig.at/post/18607051916/sentry-and-raven-setup-for-django-projects

Resources