
Slack Magic Link (Passwordless) Login
Slack has this feature “Magic link” which allows user to login into the slack app without password. This Passwordless login system is very convenient for end users, because the user don’t have to remember and type the password. This “Magic Link” method just requires the user to enter their email address and they have to verify their identity by clicking the link sent to the email address provided.
We can implement passwordless login system in django with django-sesame library.
django sesamedjango-sesame provides one-click login for your Django project. It uses specially crafted URLs containing an authentication token, for example: http://example.com/?url_auth_token=XXXXXXXXXX
Here user’s identity is verified using the auth token present in the url.
SetupClone this repo and install requirements.
Install requirements pip install -r requirements.txt Configure Django project to use django sesameSteps needs to be done
django sesame authentication middleware django sesame authentication backend email smtp configuration (used for sending magic link via email) # settings.py # setup default login page LOGIN_URL = '/customers/login/' # add auth middleware and auth backend MIDDLEWARE += ['sesame.middleware.AuthenticationMiddleware'] AUTHENTICATION_BACKENDS += ['sesame.backends.ModelBackend'] # configure with your own smtp server settings EMAIL_HOST = "" EMAIL_PORT = 2587 EMAIL_HOST_USER = "" EMAIL_HOST_PASSWORD = "" EMAIL_USE_TLS = True DEFAULT_FROM_EMAIL = "Admin<[email protected]>"
generate login tokenSteps to generate login token, django sesame provides 2 methods that we can use to generate auth token.
1: Using get_query_string Use this method if you just want to build url with auth token.
#generate login token from django.contrib.auth.models import User from sesame import utils email = "[email protected]" user = User.objects.get(email=email) login_token = utils.get_query_string(user) login_link = "http://127.0.0.1:8000/customers/{}".format(login_token)
2: Using get_parameters Use this method if you build url on your own.
#get_parameters from django.contrib.auth.models import User from sesame import utils email = "[email protected] " user = User.objects.get(email=email) login_token = utils.get_parameters(user) login_link = "http://127.0.0.1:8000/customers/?method=magic&url_auth_token={}".format(login_token['url_auth_token'] ) #settings.py #customize auth token name SESAME_TOKEN_NAME = "url_auth_token" #settings.py # set token expiry SESAME_MAX_AGE = 6 * 60 * 60 # 6 hour Send emailMake sure you have configured emails in settings.py
#settings.py #send email from django.core.mail import send_mail html_message = """ <p>Hi there,</p> <p>Here is your <a href="{}">magic link</a> </p> <p>Thanks,</p> <p>Django Admin</p> """.format(login_link) send_mail( 'Django Magic Link', html_message, [email protected] ', [email], fail_silently=True, html_message = html_message ) Create a login page <!--login.html--> <form class="form" action="{% url 'customers-login' %}" method="POST"> {% csrf_token %} <div class="form-group"> <input type="email" value="" id="emailId" name="emailId" class="form-control" placeholder="Email Address" required> </div> <button class="btn btn-danger" type="submit">Send Me Magic Link</button> </form> {% if message %} <div class="card card-block card-inverse card-success text-xs-center"> <blockquote class="card-blockquote"> <p>Magic Link sent to your email address.</p> </blockquote> </div> {% endif %} Django Magic Linkputting it all together.
#views.py from django.shortcuts import render from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required from sesame import utils from django.core.mail import send_mail def login_page(request): if request.method == "POST": email = request.POST.get("emailId") user = User.objects.get(email=email) login_token = utils.get_query_string(user) login_link = "http://127.0.0.1:8000/customers/{}".format(login_token) html_message = """ <p>Hi there,</p> <p>Here is your <a href="{}">magic link</a> </p> <p>Thanks,</p> <p>Django Admin</p> """.format(login_link) send_mail( 'Django Magic Link', html_message, [email protected] ', [email], fail_silently=False, html_message = html_message ) return render(request, "login.html", context={"message":"Please check your email for magic link."}) return render(request, "login.html") @login_required def customers_home_page(request): return render(request, "customers/index.html")