Package: django-rest-authemail
django-rest-authemaildjango-rest-authemailis a Django/Python application that provides a RESTful API interface for user signup and authentication.  Email addresses are used for authentication, rather than usernames.  Because the authentication user model is based on Django'sAbstractBaseUserand is itself abstract, the model can be extended without the need for additional database tables.  Token authentication allows the API to be accessed from a variety of front ends, including Django, React and AngularJS clients, and iOS and Android mobile apps.FeaturesAPI endpoints for signup, signup email verification, login, logout, password reset, password reset verification, password change, email change, and user detail.Extensible abstract user model.Perform password confirmation and other client-side validation on the front end for a better user experience.Token authentication.User models in the admin interface include inlines for signup and password reset codes.An example project is included and contains example UI templates.Version2.0.5and beyondSupports and tested with Python 3.6, 3.7, and 3.8.Supports and tested with Django 2.2.8, 2.2.13, 3.0, 3.1, and 3.2.Supports and tested with Django REST Framework 3.11.2 and 3.12.4.Version1.10.2Supports and tested with Python 3.6 and 3.7.Supports and tested with Django 1.11.17, 2.0, and 2.1.1.Supports and tested with Django REST Framework 3.7.1 and 3.11.0.Installationdjango-rest-authemailis available on the Python Package Index (PyPI) athttps://pypi.python.org/pypi/django-rest-authemail.Installdjango-rest-authemailusing one of the following techniques.Use pip.  Note that particular versions of Django and the Django REST Framework may be installed.pip install django-rest-authemailDownload the .tar.gz file from PyPI and install it yourself.Download thesource from Githuband install it yourself.If you install it yourself, also installDjango, theDjango REST Framework, andrequests.UsageCreate a Django project, if you haven't already. For example,django-adminstartprojectmysiteIn thesettings.pyfile of your project, includerest_frameworkandrest_framework.authtokeninINSTALLED_APPS. Set the authentication scheme for the Django REST Framework toTokenAuthentication.mysite/settings.py----INSTALLED_APPS=[...'rest_framework','rest_framework.authtoken',...]REST_FRAMEWORK={'DEFAULT_AUTHENTICATION_CLASSES':('rest_framework.authentication.TokenAuthentication',)}Optionally, you may add anAUTH_EMAIL_VERIFICATIONsetting to specify whether to enable email verification for new users on account registration/signup. Setting this toFalsewill automatically verify newly created users.Create a Django application for your user data.  For example,pythonmanage.pystartappaccountsIn themodels.pyfile of your application, extendEmailAbstractUser, add custom fields, and assignobjectstoEmailUserManager().  For example,accounts/models.py----fromdjango.dbimportmodelsfromauthemail.modelsimportEmailUserManager,EmailAbstractUserclassMyUser(EmailAbstractUser):# Custom fieldsdate_of_birth=models.DateField('Date of birth',null=True,blank=True)# Requiredobjects=EmailUserManager()In thesettings.pyfile of your project, includeauthemailand your application inINSTALLED_APPS. SetAUTH_USER_MODELto the class of your user model.  For example,mysite/settings.py----INSTALLED_APPS=[...'rest_framework','rest_framework.authtoken','authemail','accounts',...]AUTH_USER_MODEL='accounts.MyUser'In theadmin.pyfile of your project, extendEmailUserAdminto add your custom fields.  For example,mysite/admin.py----fromdjango.contribimportadminfromdjango.contrib.authimportget_user_modelfromauthemail.adminimportEmailUserAdminclassMyUserAdmin(EmailUserAdmin):fieldsets=((None,{'fields':('email','password')}),('Personal Info',{'fields':('first_name','last_name')}),('Permissions',{'fields':('is_active','is_staff','is_superuser','is_verified','groups','user_permissions')}),('Important dates',{'fields':('last_login','date_joined')}),('Custom info',{'fields':('date_of_birth',)}),)admin.site.unregister(get_user_model())admin.site.register(get_user_model(),MyUserAdmin)Create the database tables with Django'smakemigrations,migrate, and create a superuser withcreatesuperuser.pythonmanage.pymakemigrationspythonmanage.pymigratepythonmanage.pycreatesuperuserCheck your setup by starting a Web server on your local machine:pythonmanage.pyrunserverDirect your browser to theDjango/adminand log in.127.0.0.1:8000/adminYou should seeUsers,Tokens,Password reset codes,Signup codes, andGroups.  If you click onUsers, you should see your superuser account.Add theauthemailAPI endpoints to your project'surls.pyfile.  For example,mysite/urls.py----fromdjango.contribimportadminfromdjango.urlsimportinclude,pathurlpatterns=[path('admin/',admin.site.urls),path('api/accounts/',include('authemail.urls')),]When users signup or reset their password, they will be sent an email with a link and verification code.  Include email settings as environment variables or in your project'ssettings.pyfile.  For example,mysite/settings.py----# Email settings# https://docs.djangoproject.com/en/3.1/topics/email/# https://docs.djangoproject.com/en/3.1/ref/settings/#email-hostimportosEMAIL_FROM=os.environ.get('AUTHEMAIL_DEFAULT_EMAIL_FROM')or'<YOUR DEFAULT_EMAIL_FROM HERE>'EMAIL_BCC=os.environ.get('AUTHEMAIL_DEFAULT_EMAIL_BCC')or'<YOUR DEFAULT_EMAIL_BCC HERE>'EMAIL_HOST=os.environ.get('AUTHEMAIL_EMAIL_HOST')or'smtp.gmail.com'EMAIL_PORT=os.environ.get('AUTHEMAIL_EMAIL_PORT')or587EMAIL_HOST_USER=os.environ.get('AUTHEMAIL_EMAIL_HOST_USER')or'<YOUR EMAIL_HOST_USER HERE>'EMAIL_HOST_PASSWORD=os.environ.get('AUTHEMAIL_EMAIL_HOST_PASSWORD')or'<YOUR EMAIL_HOST_PASSWORD HERE>'EMAIL_USE_TLS=TrueEMAIL_USE_SSL=FalseTry outauthemailAPI calls by firing uppythonand using theauthemailwrapper methods (runservershould still be executing).  For example,python>>>fromauthemailimportwrapper>>>account=wrapper.Authemail()>>>first_name='Your first name'>>>last_name='Your last name'>>>email='your_email@gmail.com'>>>password='Your password'>>>response=account.signup(first_name=first_name,last_name=last_name,...email=email,password=password)In theDjango/admin, you should see a new user (not verified) and a new signup code.  You should receive an email atyour_email@gmail.com.  Use the code in the email to verify your email address using the wrapper (normally, the link in the email would point to the front end, which would issue the signup verify request to the API):>>>code='7f31e7a515df266532df4e00e0cf1967a7de7d17'>>>response=account.signup_verify(code=code)In theDjango/admin, the new user is now verified and the signup code is absent.  The new user can now login and you can inspect the associated login token:>>>response=account.login(email=email,password=password)>>>account.token'a84d062c1b60a36e6740eb60c6f9da8d1f709322'You will find the same token for the user in theTokentable in theDjango/admin.  Find out more information about the user (insert your token):>>>token='a84d062c1b60a36e6740eb60c6f9da8d1f709322'>>>response=account.users_me(token=token)>>>response{'id':1,'first_name':'Your first name','last_name':'Your last name','email':'your_email@gmail.com'}Use the authentication token to logout:>>>response=account.logout(token=token)>>>response{'success':'User logged out.'}Play with password reset and change!Django REST Framework Browsable APIIf you are having trouble getting your code to execute, or are just curious, try out the Django REST Framework Browsable API.  If you type anauthemailAPI endpoint into your browser, the Browsable API should appear (runservershould still be executing).  For example,127.0.0.1:8000/api/accounts/signupEnter information in the HTML form fields of the Browsable API, e.g.:Then click onPOST.  You will either receive an error message to help in your debugging, or, if your signup was successful:Try out the otherauthemailAPI endpoints with the Django REST Framework Browsable API.Front End Example ProjectMakeauthemailAPI calls from front end code.  To get started, follow the steps in theexample_projectREADME.md.  Enhance the Django code in theexample_projector extend the concepts to React, AngularJS, iOS, and Android front ends.When calling endpoints from the front end that require authentication (logout,password/change, andusers/me), include the authorization token key in the HTTP header.  For example,Authorization:Token9944b09199c62bcf9418ad846dd0e4bbdfc6ee4bHere's an example usingcurl,curl-XGET'http://127.0.0.1:8000/api/accounts/logout/'\-H'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'WrapperA wrapper is available to access the Authemail API with Python code.  First create an instance of the Authemail class, then call methods to access the API.  There is a one-to-one mapping between the endpoints and instance methods.  For example,mysite/views.py----fromauthemailimportwrapperaccount=wrapper.Authemail()response=account.signup(first_name=first_name,last_name=last_name,email=email,password=password)if'detail'inresponse:# Handle error conditionelse:# Handle good responseSeeexample_project/views.pyfor more sample usage.Authemail API EndpointsFor the endpoints that follow, the base path is shown as/api/accounts.  This path is for example purposes.  It can be customized in your project'surls.pyfile.POST /api/accounts/signupCall this endpoint to sign up a new user and send a verification email.  Sample email templates are found inauthemail/templates/authemail.  To override the email templates, copy and modify the sample templates, or create your own, inyour_app/templates/authemail.Your front end should handle password confirmation, and if desired, require the visitor to input their first and last names.Unverified users can sign up multiple times, but only the latest signup code will be active.Payloademail (required)password (required)first_name (optional)last_name (optional)Possible responses201(Created)Content-Type:application/json{"email":"amelia.earhart@boeing.com""first_name":"Amelia","last_name":"Earhart",}400(BadRequest)Content-Type:application/json{"email":["This field may not be blank."],"password":["This field may not be blank."]}{"email":["Enter a valid email address."]}{"detail":"User with this Email address already exists."}GET /api/accounts/signup/verify/?code=<code>When the user clicks the link in the verification email, the front end should call this endpoint to verify the user.Parameterscode (required)Possible responses200(OK)Content-Type:application/json{"success":"User verified."}400(BadRequest)Content-Type:application/json{"detail":"Unable to verify user."}POST /api/accounts/loginCall this endpoint to log in a user.  Use the authentication token in future calls to identify the user.Payloademail (required)password (required)Possible responses200(OK)Content-Type:application/json{"token":"91ec67d093ded89e0a752f35188802c261899013"}400(BadRequest)Content-Type:application/json{"password":["This field may not be blank."],"email":["This field may not be blank."]}{"email":["Enter a valid email address."]}401(Unauthorized){"detail":"Authentication credentials were not provided."}{"detail":"Unable to login with provided credentials."}GET /api/accounts/logoutCall this endpoint to log out an authenticated user.HTTP HeaderAuthorization:Token9944b09199c62bcf9418ad846dd0e4bbdfc6ee4bPossible responses200(OK)Content-Type:application/json{"success":"User logged out."}401(Unauthorized)Content-Type:application/json{"detail":"Authentication credentials were not provided."}{"detail":"Invalid token"}POST /api/accounts/password/resetCall this endpoint to send an email to a user so they can reset their password.   Similar to signup verification, the password reset email templates are found inauthemail/templates/authemail.  Override the default templates by placing your similarly-named templates inyour_app/templates/authemail.Payloademail (required)Possible responses201(Created)Content-Type:application/json{"email":"amelia.earhart@boeing.com"}400(BadRequest)Content-Type:application/json{"email":["This field may not be blank."]}{"email":["Enter a valid email address."]}{"detail":"Password reset not allowed."}GET /api/accounts/password/reset/verify/?code=<code>When the user clicks the link in the password reset email, call this endpoint
to verify the password reset code.Parameterscode (required)Possible responses200(OK)Content-Type:application/json{"success":"User verified."}400(BadRequest)Content-Type:application/json{"password":["This field may not be blank."]}{"detail":"Unable to verify user."}POST /api/accounts/password/reset/verifiedCall this endpoint with the password reset code and the new password, to reset
the user's password.  The front end should prompt the user for a confirmation
password and give feedback if the passwords don't match.Payloadcode (required)password (required)Possible responses200(OK)Content-Type:application/json{"success":"Password reset."}400(BadRequest)Content-Type:application/json{"password":["This field may not be blank."]}{"detail":"Unable to verify user."}POST /api/accounts/email/changeCall this endpoint to send a notification email to the previous email address
and a confirmation email to the new email address.  Similar to signup and
password reset verification, the email change email templates are found inauthemail/templates/authemail.  Override the default templates by placing
your similarly-named templates inyour_app/templates/authemail.HTTP HeaderAuthorization:Token9944b09199c62bcf9418ad846dd0e4bbdfc6ee4bPayloademail (required)Possible responses201(Created)Content-Type:application/json{"email":"amelia.earhart@boeing.com"}400(BadRequest)Content-Type:application/json{"email":["This field may not be blank."]}{"email":["Enter a valid email address."]}{"detail":"Email address already taken."}401(Unauthorized)Content-Type:application/json{"detail":"Authentication credentials were not provided."}{"detail":"Invalid token"}GET /api/accounts/email/change/verify/?code=<code>When the user clicks the link in the email change email, call this endpoint to
verify the email change code and, if appropriate, change the email address.Parameterscode (required)Possible responses200(OK)Content-Type:application/json{"success":"Email address changed."}400(BadRequest)Content-Type:application/json{"detail":"Email address already taken."}{"detail":"Unable to verify user."}POST /api/accounts/password/changeCall this endpoint to change a user's password.HTTP HeaderAuthorization:Token9944b09199c62bcf9418ad846dd0e4bbdfc6ee4bPayloadpassword (required)Possible responses200(OK)Content-Type:application/json{"success":"Password changed."}400(BadRequest)Content-Type:application/json{"password":["This field may not be blank."]}401(Unauthorized)Content-Type:application/json{"detail":"Authentication credentials were not provided."}{"detail":"Invalid token"}GET /api/accounts/users/meCall this endpoint after logging in and obtaining an authorization token to learn more about the user.HTTP HeaderAuthorization:Token9944b09199c62bcf9418ad846dd0e4bbdfc6ee4bPossible responses200(OK)Content-Type:application/json{"id":1,"email":"amelia.earhart@boeing.com","first_name":"Amelia","last_name":"Earhart",}401(Unauthorized)Content-Type:application/json{"detail":"Authentication credentials were not provided."}{"detail":"Invalid token"}Django Packagesdjango-rest-authemailcan be found on Django Packages athttps://djangopackages.org/packages/p/django-rest-authemail/.django-rest-authemailcan be found in the Django REST Framework Comparison Grid athttps://djangopackages.org/grids/g/django-rest-framework/.Inspiration and IdeasInspiration and ideas fordjango-rest-authemailwere derived from:django-rest-frameworkdjango-email-as-usernamedjango-registrationdjango-rest-authtmdbsimple