Я не совсем уверен в деталях реализации и том, как создается токен (но я уверен, что флеш-защита использует itsdangerous
).
Главное использование токена - не хранить секреты, которые вы не хотите видеть, потому что токен может быть легко декодирован и просмотрен кем-либо (вот почему был сделан дополнительный шаг для хранения хэша пароля который не может быть расшифрован).
Маркер используется для передачи данных из одного источника (клиента) к другому (сервер) и убедитесь, что данные не Modified или изменено любым
Да любой может заглянуть внутрь и посмотреть, что содержится в токене, дело в том, что без секретного ключа никто не может вмешиваться в данные, если злоумышленник генерирует свой собственный токен, он должен сделать это с помощью secret key
, иначе токен будет отклонен флагом, поскольку он не действительный.
Вот краткий демо о том, что я имею в виду, используя itsdangerous (Колба сама использует эту библиотеку для сеансов)
Давайте предположим, что в вашем приложении вы только предоставить доступ администратора пользователям, проверяя, если они имеют набор параметров is_admin
до 'true'
в токене.
Пользователь, не являющийся администратором, Джон аутентифицируется и получает свой токен, отправленный ему.
from itsdangerous import URLSafeSerializer
>>> s = URLSafeSerializer('secret key')
>>> s.dumps({'username': 'john', 'is_admin': 'false'})
'eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6ImZhbHNlIn0.k45WPrVOG1Nrags0bwpVUbS7Vcw'
Как-то вдоль линии, злоумышленник перехватывает маркер и быть достаточно умен, он знает, что лексемы в формате base64 строки, так что они могут быть легко декодируется обратно обратно к своей первоначальной форме. Для этого у Python даже есть модуль в стандартной библиотеке, поэтому он не должен подчеркивать себя.
import base64
>>> base64.b64decode('eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6ImZhbHNlIn0===')
b'{"username":"john","is_admin":"false"}'
Просто нравится, что он способен декодировать наш маркер и посмотреть, что внутри (Вот почему пароль был хэшируются для дополнительной безопасности)
Поскольку он знает параметры, мы ожидаем, что было бы естественно предположить, что любой пользователь, у которого есть is_admin
, установленный в true
, имеет больше доступа к вещам, которые обычный пользователь не хочет, затем он начинает генерировать свой собственный токен.
Поскольку он не наш сервер в секрете, он просто использует случайный секрет
>>> t = URLSafeSerializer('fake key')
>>> t.dumps({'username': 'john', 'is_admin': 'true'})
'eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6InRydWUifQ.fPUeGmfSaQWCysy5WWTmmMeuo6c'
Хорошо, тогда он посылает маркер на наш сервер.
Когда мы пытаемся декодировать токен с помощью нашего Serializer (который был настроен для использования нашего ключа сервера), мы получим сообщение об ошибке. и злоумышленник не может войти, потому что он использовал не тот секрет, чтобы подписать свой токен.
>>> s.loads('eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6InRydWUifQ.fPUeGmfSaQWCysy5WWTmmMeuo6c')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/danidee/venv/lib/python3.5/site-packages/itsdangerous.py", line 582, in loads
return self.load_payload(self.make_signer(salt).unsign(s))
File "/home/danidee/venv/lib/python3.5/site-packages/itsdangerous.py", line 374, in unsign
payload=value)
itsdangerous.BadSignature: Signature b'fPUeGmfSaQWCysy5WWTmmMeuo6c' does not match
>>>
Сервер может проверять только токены, которые были подписаны с помощью ключа, который он имеет. Если ваш серверный ключ не был взломан, вам не нужно беспокоиться о том, чтобы кто-либо отправлял измененные данные в ваше приложение.
Вы только должны удостовериться, что вы не храните «реальные секреты» в маркере
# We can always load the correct token back
s.loads('eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6ImZhbHNlIn0.k45WPrVOG1Nrags0bwpVUbS7Vcw')
{'username': 'john', 'is_admin': 'false'}
Даже если вы пытаетесь прикрепить подпись справа знак на неправильные данные не будут действительным, и вы все равно получите ошибку
s.loads('eyJ1c2VybmFtZSI6ImpvaG4iLCJpc19hZG1pbiI6InRydWUifQ.k45WPrVOG1Nrags0bwpVUbS7Vcw')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/danidee/venv/lib/python3.5/site-packages/itsdangerous.py", line 582, in loads
return self.load_payload(self.make_signer(salt).unsign(s))
File "/home/danidee/venv/lib/python3.5/site-packages/itsdangerous.py", line 374, in unsign
payload=value)
itsdangerous.BadSignature: Signature b'k45WPrVOG1Nrags0bwpVUbS7Vcw' does not match
Отказ от ответственности: Это может быть не точной реализации в безопасности опоки, но мой ответ должен дать вам представление о том, что происходит за кулисами. Вы также можете прочитать JSON web tokens
и не хранить ваши секреты в своем конфигурационном файле, сохранить его в .env
(который не будет частью контроля источника) или сделать его переменной окружения и EXPORT/SET переменная в производственной среде.
Оформить заказ dotenv
благодарит за отличный ответ! Это делает проблему намного яснее. Теперь я понимаю, что нам нужно перевести секретный ключ в файл конфигурации или env var. – mcouthon