Package: rest-multi-factor
REST multi factorA multi factor implementation for the django rest frameworkOverviewA package that allows for a flexible multi factor implementation.RequirementsPython (3.5, 3.6, 3.7)Django (1.11 or 2.2+)Django rest framework (3.10+)installationInstall using pip$pipinstallrest-multi-factorOr if you wan't to include QR-codes for the registration responses of
devices like TOTP (for google authenticator) use$pipinstallrest-multi-factor[qr]Add"rest_multi_factor"toINSTALLED_APPSin you're django settings.
For the different multi factor types like TOTP (for google authenticator)
you also need to add the plugin name.INSTALLED_APPS=[# ..."rest_multi_factor","rest_multi_factor.plugins.totp",]It is advised to adddjango-rest-knoxas you're token manager. Please
read the 'security concerns' section belowbeforeimplementation.Resource descriptionTerminologynamemeaningdevicea method of multi factor (e.g. TOTP, email)challengethe relation of a device and tokenverificationchecking if a OTP value belongs to a tokenregistrationregistering a device to a userOverviewMethodResourceDescriptionGET/multi-factor/Overview of the current users devicesGET/multi-factor/:index/Specifics of a registered devicePOST/multi-factor/:index/Validate the current tokenPOST/multi-factor/:index/dispatch/Dispatch a challenge (send the value)GET/multi-factor/register/Get a overview of the available devicesPOST/multi-factor/register/:index/Register a new device for the current userSecurity concernsWith default configuration are a few security concerns that you might
want to solve within you're application:REST framework's authtoken Vs. knoxWhile by default the rest_framework's authtoken app is configured, do
we advice to use knox. This is because knox hashes the tokens before
they are stored in the database.To resolve this issue you can set the following configurations:REST_MULTI_FACTOR={"AUTH_TOKEN_MODEL":"knox.AuthToken",}and install knox as described here:http://james1345.github.io/django-rest-knox/installation/#installing-knoxPlease note: Because django has no (public) swappable relation
mechanism is it advices to do this before you make the migrations.
Otherwise you have to remove the migrations, change the settings and
re-make the migrations.MultiFactorRegistrationViewSet permissionsBy default will the registration use theIsVerifiedOrNoDevice. This
will allow a user that has no registered devices to register a device
for himself before he can continue.  If you don't need this behaviour it is
strongly advised to override the view like this:"""Viewsets within foobar/viewsets.py"""fromrest_multi_factor.viewsetsimportMultiFactorRegistrationViewSetfromrest_multi_factor.permissionsimportIsVerifiedclassRegistrationViewSet(MultiFactorRegistrationViewSet):"""Private registration viewset."""permission_classes=(IsVerified,)Than you can update you're urls.py like this:"""Urls within project/urls.py"""fromdjango.conf.urlsimporturl,includefromrest_multi_factor.routersimportMultiFactorVerifierRouterfromrest_multi_factor.routersimportMultiFactorRegisterRouterfromrest_multi_factor.viewsetsimportMultiFactorVerifierViewSetfromfoobar.viewsetsimportRegistrationViewSetverifier_router=MultiFactorVerifierRouter()verifier_router.register("",MultiFactorVerifierViewSet,"multi-factor")register_router=MultiFactorRegisterRouter()register_router.register("register",RegistrationViewSet,"multi-factor-register")urlpatterns=[url(r"^multi-factor/",include(verifier_router.urls)),url(r"^multi-factor/",include(register_router.urls)),]