Найти тему
Django stack

Как в Django быстренько сгенерить magic link?

Оглавление

Photo by Nubelson Fernandes on Unsplash
Photo by Nubelson Fernandes on Unsplash

Введение

По своей сути magiс link это ссылка со строкой. Эта строка - ключ, который, для валидации, может потребовать обращения к базе данных (БД), а может не потребовать.

В первом случае, просто генерим рандомный токен, сохраняем его в БД и валидируем его обращаясь к БД - ну так себе...

Во втором, генерим подпись на основе наших осмысленных прикладных данных. Для валидации ключа не потребуется обращение к БД.

К делу

В Django есть модуль который позволяет сгенерить строку, совместимую с форматом url, из json обьектов - django.core.signing.

Поскольку речь про подпись, то важно знать вот что: ключом для нее, по умолчанию, будет знаменитая settings.SECRET_KEY. Таким образом, позаботится о приватности этой настройки - обязанность ответственного разработчика. Говорят, это к удачи.

В модуле есть 2 функции-обертки:

  • dumps
  • loads

Они ползовлят "запаковать" данные и "распаковать" их быстро не вникая в возможности и реализацию классов в модуле.

условная последовательность формирования и пересылки данных
условная последовательность формирования и пересылки данных

Пример

Пользователь с email: foo@boo.com хочет "войти" в систему. В html форме он вводит свой email. Мы создаем dict вида: {"email":"foo.boo.com"}.

Далее, вызываем метод: signing.dumps({"email":"foo.boo.com"}).

Получаем строку вида: "eyJlbWFpbCI6InRlc3RfbWF4aW1fZmF2ZUBmb28uYm9vIiwidGVuYW50X2lkIjoiYzMyNmU1YTItYWQ4Yi00MjQ0LWJlZDEtYjQwZWE1NDMwZTNlIn0:1rECzl:q1DpDaZrWS9G33HAtUfUZwSfgfxOxRwh2p4nJutdf_E", которую можно использовать в адресной строке браузера (и соответственно получить ее оттуда).

Собрать magic link уже дело техники: https://app.com/auth/signin?token=<СТРОКА>

Что бы из этой строки получить обратно тот самый dict, то есть провести обратную операцию, надо воспользоваться методом: signing.loads(token), где token это переменная со значением вышеупомянутой строки.

Метод loads так же принимает параметр max_age, который валидирует возраст данных. Например, мы можем ограничить срок жизни данных 10 минутами, тогда: max_age=600.

пример использования обертки из модуля signing
пример использования обертки из модуля signing

Текст примера из скрина доступен тут.

Для более детального ознакомления я strongly рекомендую почитать доки - там все очень лаконично.