5.1 KiB
SQRL for Django
This package allows for developers to easily create SQRL-aware websites with a few simple steps.
(This document was written for the future. Things that are not yet implemented
will be struck out. Non-functional code snippets will be #commented out
)
This is a reboot of Miki725's django-sqrl, updated for Python 3.7 and Django 2.2. The vast majority of the code is unchanged, so all credit for this working belongs with them.
- Free software: MIT license
- Git: https://gitlab.com/WolfgangAxel/django-sqrl-2
Documentation: https://django-sqrl-2.readthedocs.org- What is SQRL?: https://sqrl.grc.com/pages/what_is_sqrl/
- SQRL documentation: https://www.grc.com/sqrl/sqrl.htm
Installing
SQRL Package
First step is to install django-sqrl-2
which is easies to do using pip:
$ #python3 -m pip install django-sqrl-2
Django settings
Once installed there are a few required changes in Django settings:
- Make sure that some required Django apps are used:
INSTALLED_APPS = [
...,
'sqrl',
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.staticfiles',
...
]
- Make sure that some required Django middleware are used:
MIDDLEWARE_CLASSES = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
]
- Change
AUTHENTICATION_BACKENDS
to use SQRL backend vs Django'sModelBackend
(default):
AUTHENTICATION_BACKENDS = [
'sqrl.backends.SQRLModelBackend',
]
-
If you are using Django admin, following are required:
-
Make sure that
sqrl
is listed beforeadmin
in theINSTALLED_APPS
. This allows Django to prioritizesqrl
templates sincedjango-sqrl
overwrites some of them.
INSTALLED_APPS = [
...,
'sqrl',
'django.contrib.admin',
...
]
- Make sure to add a custom template directory in settings.
django-sqrl
extends Django admin'sbase.html
which by default causes infinite recursion. To solve that, simply add a custom template directory which allowsdjango-sqrl
to explicitly extend fromdjango.contrib.admin
base.html
template:
import os
import django
TEMPLATE_DIRS = [
os.path.dirname(django.__file__),
]
URLs
All of SQRL functionality is enabled by adding its URLs to the root URL config:
from django.urls import path, include
urlpatterns = [
...
path('sqrl/', include('sqrl.urls', namespace="sqrl")),
...
]
If you use Django admin, the /admin/sqrl_manage
endpoint will be available to manage
your site's SQRL identities.
Templates
Now that SQRL is installed in your Django project, you can use it on any login page with three simple template tags:
{% load sqrl %}
{% sqrl as sqrl_session %}
{% sqrl_login_dropin sqrl_session "named:redirect" %}
The "named:redirect"
is the page that should be redirected to after logging
in. Any name that can be resolved by django's reverse
function will work. For
example, here are the necessary lines needed to resolve "app:main"
:
- Main project's
urls.py
:
urlpatterns = [
...
path("", include('app.urls', namespace="app"))
...
]
- Your
app
'surls.py
:
urlpatterns = [
...
path("", main_view, name="main")
...
]
- Your
main_view
's template:
...
{% load sqrl %}
{% sqrl as sqrl_session %}
{% sqrl_login_dropin sqrl_session "app:main" %}
...
These three tags will add a simple element to your login page:
If that doesn't suit your fancy, you may build your own template from the following essential tags:
{% load static %}
{% load sqrl %}
{% sqrl as sqrl_session %}
{% if session_sqrl.sqrl_url %}
<a href="{{ sqrl_session.sqrl_url }}">
<div id="sqrl-qr" data-sqrl="{{ sqrl_session.sqrl_url }}"></div>
</a>
<script>SQRL_NEXT="{{ your desired redirect (not namespace) }}"; SQRL_CHECK_URL="{% sqrl_status_url_script_tag sqrl_session %}"</script>
<script type="application/javascript" src="{% static 'sqrl/sqrl.js' %}"></script>
{% else $}
<p>You are not connected via HTTPS, therefore you may not log in using SQRL.</p>
{% endif %}
Note that the session_sqrl.sqrl_url
function will return None
if the user
connects over an insecure HTTP connection. If you make your own template, please
be sure to account for this situation as in the above example.
Management Command
SQRL uses server state to keep track of open SQRL transactions in order to
mitigate replay attacks. Since this state will constantly grow if not cleared,
django-sqrl
provides a helper management command to clear expired states:
$ python3 manage.py clearsqrlnuts
It is recommended to run this command as repeating task. Here is an example
configuration for cron
:
*/5 * * * * python manage.py clearsqrlnuts >/dev/null 2>&1
Testing
To run the tests, you need to install the testing requirements first:
$ #make install
Then to run the tests, you can use use the Makefile command:
$ #make test