# 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](https://github.com/miki725/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 * GitHub: 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's `ModelBackend` (default): ``` AUTHENTICATION_BACKENDS = [ 'sqrl.backends.SQRLModelBackend', ] ``` * If you are using Django admin, following are required: * Make sure that `sqrl` is listed before `admin` in the `INSTALLED_APPS`. This allows Django to prioritize `sqrl` templates since `django-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's `base.html` which by default causes infinite recursion. To solve that, simply add a custom template directory which allows `django-sqrl` to explicitly extend from `django.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`'s `urls.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: ![A very basic SQRL QR code](docs/example_dropin.png "example dropin") If that doesn't suit your fancy, you may build your own template from the following essential tags: ``` {% load sqrl %} {% sqrl as sqrl_session %}
``` ## 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 ```