Package: django-drf-otp
Django DRF OTPDjango DRF OTP enables otp authorization.
This module depends onDjango Rest Frameworkmodule.InstallationAdddjango_drf_otpand requirements to yourINSTALLED_APPSsetting.INSTALLED_APPS=[...,"rest_framework",# Requirement"rest_framework.authtoken",# Requirement"django_drf_otp",...]If you're intending to use the base auth API you'll probably also want to
add Django DRF OTP's login and logout views.
Add the following to your rooturls.pyfile.urlpatterns=[...,path("api-auth/",include("django_drf_otp.urls")),...]Django DRF OTP provides two endpointslogin/andverify-token/:login: Validates user with givenUSERNAME_FIELDandpassword.
By the default returns a success message.verify-token: Validates the otp token with giventoken.
By the default returns a token
(from Rest Framework's Token[link]model).And finally runpython manage.py migrateto create models.ContentsSettingsViewSetsStrategiesSettingsConfiguration for Django DRF OTP is all namespaced inside
a single Django setting, namedOTP_SETTINGS.For example your project's settings.py file might include something like this:OTP_SETTINGS={"ENABLE_OTP_AUTHENTICATION":True,}Accessing settingsIf you need to access the values of REST framework's API settings
in your project, you should use the api_settings object. For example.fromdjango_drf_otp.settingsimportotp_settingsprint(api_settings.ENABLE_OTP_AUTHORIZATION)API ReferenceAPI policy settingsThe following settings control the basic API policies.ENABLE_OTP_AUTHENTICATIONEnables or Disables OTP Authorization.Default:TrueTOKEN_LENGTHThe default token length to use for otp token creation.Default:TrueTOKEN_SECRETThe default token creation secret characters.Default:'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'DEFAULT_TOKEN_TYPEThe default token type to use for otp token creation.Default:TOTPTOTP_TOKEN_TTLThe default otp token ttl value.Default:300EMAIL_CONFIGA dict of email config that used by otp email template.Default:{"SUBJECT":_("Verification Token"),"TEMPLATE_PATH":"django_drf_otp/email.html",}SUBJECT: Subject of email.TEMPLATE_PATH: The template used for email body.ViewSetsOTPTokenViewSetTheOTPTokenViewSetclass inherits from Rest Framework'sGenericViewSet(link).
This viewset provides actions:login,verify_tokenand provides methods:get_success_response_data,get_extra_context_data.fromrest_frameworkimportviewsetsfromdjango_drf_otp.servicesimportOTPServicefromdjango_drf_otp.serializersimportOTPTokenSerializer,OTPTokenVerifySerializerclassOTPTokenViewSet(viewsets.GenericViewSet):permission_classes=(AllowAny,)serializer_classes={"login":OTPTokenSerializer,"verify_token":OTPTokenVerifySerializer,}def__init__(self,**kwargs:Any)->None:super().__init__(**kwargs)self.OTP_ENABLED=otp_settings.ENABLE_OTP_AUTHENTICATIONdeflogin(self,request:Request,*args,**kwargs):...defverify_token(self,request:Request,*args,**kwargs):...defget_serializer_class(self,*args,**kwargs)->Type[serializers.Serializer]:...defget_success_response_data(self,validated_data:Dict,**kwargs)->Dict:...defget_extra_context_data(self,request:Request,validated_data:Dict)->Dict:...API attributespermission_classesA tuple. Rest Framework'spermission_classes[link]attribute.Default:permission_classes=(AllowAny,)serializer_classesA dict contains the action&serializer pair. This attribute used byget_serializer_class[link]that returns a serializer according toaction[link].Default:serializer_classes={"login":OTPTokenSerializer,"verify_token":OTPTokenVerifySerializer,}API actions&methodsloginThis action validates the user and
send a token based on the user's notification preference(Currently only email available)
ifENABLE_OTP_AUTHENTICATIONisTrue,
otherwise a token[link].
By the default usesOTPTokenSerializerfor validation.verify_tokenThis action validates the otp token and returns a token[link]ifENABLE_OTP_AUTHENTICATIONisTrue,
otherwise a error message. By the default usesOTPTokenVerifySerializerfor validation.💡Note:If you want to change validation serializer class editget_serializer_classmethod orserializer_classesattribute.
For editing responses seeget_success_response_data.get_serializer_classThis method is used to decide the serializer class and returns a serializer class.
By the default returns a serializer defined inserializer_classeswith the action[link]Default:defget_serializer_class(self,*args,**kwargs)->Type[serializers.Serializer]:returnself.serializer_classes[self.action]get_success_response_dataThis method is used to decide the response data to return to the user.
Takes the serializer's validated data is returned byget_serializer_classand returns a dict.
By the default returns the success message({"message": _("OTP token sent successfully.")}),
othervise Rest Framework's token({"token": token.key}).⚠️ Warning: If you are not overrideget_success_response_dataandget_extra_context_data,
you must provide User object withuserkey in your serializer'svalidated_dataget_extra_context_dataThis method is returns data used by notifiers.
By the default returns a dict containsrequestobject and user'sfirst_name,last_nameandfull_name.Examplefromdjango_drf_otp.viewsetsimportOTPTokenViewSetfromdjango_drf_otp.settingsimportotp_settingsfrom.serializersimportCustomLoginSerializer,CustomTokenVerifySerializerclassLoginViewSet(OTPTokenViewSet):defget_serializer_class(self,*args,**kwargs)->Type[serializers.Serializer]:ifself.action=="login":returnCustomLoginSerializerelse:returnCustomTokenVerifySerializerdefget_success_response_data(self,validated_data:Dict,**kwargs)->Dict:ifself.action=="login"andotp_settings.ENABLE_OTP_AUTHENTICATION:returnvalidated_dataelse:token,return{"token":}StrategiesStrategies are used to generate otp tokens with different token algorithms
(only TOTP tokens are available for now).
This module usespyotpmodule for a token creation.Class's attributestoken_typeA string attribute. It can be one of the values defined in TokenType(defined indjango_drf_otp.enums).API methodsgenerate_tokenA abstract method. This method used to create a otp token.
Returns token string.
If you want to implement a new strategy, must be overrided.Default (inBaseOTPStrategy):@abstractmethoddefgenerate_token(self,extra_secret_chars:Optional[str]=None)->str:NotImplementedError()verify_tokenThis method used to verify a otp token.
ReturnsTrueif the token is verified, otherwiseFalse.
if you want to implement a new strategy, must be overrided.Default (inBaseOTPStrategy):@abstractmethoddefverify_token(self,token:str,extra_secret_chars:Optional[str]=None)->bool:NotImplementedError()generate_token_for_userA abstract method. This method used to create a otp token for a user
viaVerificationToken(defined indjango_drf_otp.models).
If you want to implement a new strategy, must be overrided.Default (inBaseOTPStrategy):@abstractmethoddefgenerate_token_for_user(self,user:AbstractUser)->VerificationToken:NotImplementedError()create_verification_tokenA static method. This method used to create
aVerificationTokenmodel instance for user.Default (inBaseOTPStrategy):@staticmethoddefcreate_verification_token(user:AbstractUser,token:str,token_type:TokenType,secret_chars:str,)->VerificationToken:returnVerificationToken.objects.create(user=user,token=token,token_type=token_type,secret_chars=secret_chars)deactivate_old_verification_tokensA static method. This method used to deactivates
user's allVerificationTokeninstances excluding given token instance.Default (inBaseOTPStrategy):@staticmethoddefdeactivate_old_verification_tokens(verification_token:VerificationToken)->None:VerificationToken.objects.filter(user=verification_token.user,is_active=True).exclude(id=verification_token.id).update(is_active=False)ExampleYou can easily implement a new strategy for your special solutions
(with only defined token_types inTokenTypeclass).Then create a new strategy class:classCustomTOTPStrategy(BaseOTPStrategy):token_type=TokenType.TOTPdefgenerate_token(self,extra_secret_chars:Optional[str]=None)->str:# <Your code here>