Авторизация через Telegram в Django приложении

5 лет назад я написал backend-модуль для авторизации через Telegram в популярном пакете python-social-auth. С тех пор я сам регулярно использую эту фичу на своих собственных сайтах, очень удобно и быстро. Но с выходом Django 4.0 модуль авторизации через Telegram перестал работать. Почему? А всё потому что появилась настройка SECURE_CROSS_ORIGIN_OPENER_POLICY со значением по умолчанию same-origin. Что это значит? Авторизация в Telegram работает через виджет, который открывает pop-up окно с разрешением на авторизацию и передачу данных вашему веб-приложению. За это отвечает заголовок Cross-Origin-Opener-Policy.

Cross-Origin-Opener-Policy

Это HTTP заголовок, отвечающий за политику передачи контекста основного документа (откуда вызван pop-up) cross-origin документам. Заголовок может принимать три значения:

  • same-origin

Разрешение на передачу контекста основного окна в рамках одного домена или происхождения (same-origin). Т.е. если у вас есть pop-up окно, открывающееся на том же домене, то эта политика разрешит их взаимодействие (свойство window.opener не будет пустым). Начиная с версии Django 4 это значение является значением по умолчанию. Это самая безопасная политика.

  • unsafe-none

Позволяет передавать контекст между cross-origin документами при условии, что у открывающего окна (opener) та же самая политика (не является same-origin или same-origin-allow-popups)

  • same-origin-allow-popups

Передача контекста документа между same-origin документами либо теми, кто не передаёт заголовок Cross-Origin-Opener-Policy либо его значение равно unsafe-none.

В контексте авторизации через Telegram значение по умолчанию same-origin нам не подходит потому что в pop-up окне уже другой origin (oauth.telegram.org). Поэтому необходимо использовать либо unsafe-none либо same-origin-allow-popups. Второй вариант предпочтительнее, т.к. OAuth сервис Telegram не передаёт заголовок Cross-Origin-Opener-Policy.

Итог

Чтобы авторизация через Telegram корректно работала в вашем Django приложении необходимо значение константы SECURE_CROSS_ORIGIN_OPENER_POLICY в файле settings.py установить либо в None либо в same-origin-allow-popups:

SECURE_CROSS_ORIGIN_OPENER_POLICY = "same-origin-allow-popups"