<commit_before>Tutorial
========

Let's get practical.

First, we'll implement :ref:`login by email <Login by email>`, also known as
"Magic Links", in a Django project. Login by email can provide a better user
experience as users generally don't forget their email address. Keep in mind
that it requires fast and reliable email delivery.

Then, we'll create :ref:`authenticated links <Authenticated links>` to share
private content without logging in a user. As an example, a vacation rentals
service could let a customer share a booking with other travelers, while not
giving them full access to the customer's account.

The two sections are independent. Once you implement the :ref:`prerequisites
<Prerequisites>`, you may proceed with the first or the second section.

Prerequisites
-------------

Create a Django project
.......................

You may work in an existing project or you may initialize a new project as follows:

.. code-block:: console

    $ django-admin startproject tutorial
    $ cd tutorial
    $ ./manage.py migrate

If you reuse an existing project, it should enable :mod:`django.contrib.auth`.

If you have a custom user model, ensure that the email address of users is
stored in a field named ``email``. Else, you will have to adapt references
to this field.

You need a user for testing. The tutorial uses ``<EMAIL>`` in
examples. In a new project, you can create a superuser this purpose:

.. code-block:: console

    $ ./manage.py createsuperuser

Install django-sesame
.....................

Follow the instructions in the :ref:`getting started guide <Getting started>` to
install and configure django-sesame.

Login by email
--------------

We are going to build the following login flow:

1. The user provides their email address.
2. We create an authentication token and build a magic link.
3. We email the magic link to them to confirm that they own the email address.
4. The user clicks the link, we check the token, and we log them in.

Configure short-lived tokens
............................

Before we start coding, we should think about the security of the system. Tokens
are only intended to allow the user to log in now. Let's limit their validity to
5 minutes.

Open your project settings and add this line:

.. code-block:: python

    SESAME_MAX_AGE = 600  # 600 seconds = 10 minutes

Configure redirect after login
..............................

Set :setting:`LOGIN_REDIRECT_URL` to a URL that tells whether the user is
authenticated so you can easily tell whether login succeeds.

If you initialized a new project and you test with a superuser, you can simply
use the admin. Conveniently, it provides a link to log out:

.. code-block:: python

    LOGIN_REDIRECT_URL = "/admin/"

Now we can go back to building the login flow.

Create a login form
...................

Decide where you're going to add the code. In an existing project, perhaps you
already have an app for project-wide concerns; that's a good place. Otherwise,
you can create a new app.

In this app, create a login form with only one field, the email address of the
user.<commit_msg>Make example consistent with text.<commit_after>Tutorial
========

Let's get practical.

First, we'll implement :ref:`login by email <Login by email>`, also known as
"Magic Links", in a Django project. Login by email can provide a better user
experience as users generally don't forget their email address. Keep in mind
that it requires fast and reliable email delivery.

Then, we'll create :ref:`authenticated links <Authenticated links>` to share
private content without logging in a user. As an example, a vacation rentals
service could let a customer share a booking with other travelers, while not
giving them full access to the customer's account.

The two sections are independent. Once you implement the :ref:`prerequisites
<Prerequisites>`, you may proceed with the first or the second section.

Prerequisites
-------------

Create a Django project
.......................

You may work in an existing project or you may initialize a new project as follows:

.. code-block:: console

    $ django-admin startproject tutorial
    $ cd tutorial
    $ ./manage.py migrate

If you reuse an existing project, it should enable :mod:`django.contrib.auth`.

If you have a custom user model, ensure that the email address of users is
stored in a field named ``email``. Else, you will have to adapt references
to this field.

You need a user for testing. The tutorial uses ``<EMAIL>`` in
examples. In a new project, you can create a superuser this purpose:

.. code-block:: console

    $ ./manage.py createsuperuser

Install django-sesame
.....................

Follow the instructions in the :ref:`getting started guide <Getting started>` to
install and configure django-sesame.

Login by email
--------------

We are going to build the following login flow:

1. The user provides their email address.
2. We create an authentication token and build a magic link.
3. We email the magic link to them to confirm that they own the email address.
4. The user clicks the link, we check the token, and we log them in.

Configure short-lived tokens
............................

Before we start coding, we should think about the security of the system. Tokens
are only intended to allow the user to log in now. Let's limit their validity to
five minutes.

Open your project settings and add this line:

.. code-block:: python

    SESAME_MAX_AGE = 300  # 300 seconds = 5 minutes

Configure redirect after login
..............................

Set :setting:`LOGIN_REDIRECT_URL` to a URL that tells whether the user is
authenticated so you can easily tell whether login succeeds.

If you initialized a new project and you test with a superuser, you can simply
use the admin. Conveniently, it provides a link to log out:

.. code-block:: python

    LOGIN_REDIRECT_URL = "/admin/"

Now we can go back to building the login flow.

Create a login form
...................

Decide where you're going to add the code. In an existing project, perhaps you
already have an app for project-wide concerns; that's a good place. Otherwise,
you can create a new app.

In this app, create a login form with only one field, the email address of the
user.
{'fraction_non_alphanumeric': 0.10084976751643418, 'fraction_numerical': 0.003848003848003848, 'mean_word_length': 3.1865771812080537, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6048718', 'n_tokens_mistral': 1631, 'n_tokens_neox': 1537, 'n_words': 919}