Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Игорь Шевченко. Аутентификация без состояния

Игорь Шевченко. Аутентификация без состояния

Классическая модель аутентификации по HTTP — сессионная кука, которая содержит идентификатор сессии, записанной в базу данных. Но набирает популярность и другой подход: токены, содержащие всю необходимую информацию, с которыми уже не нужно хранить сессии в БД. Я опишу плюсы и минусы этого подхода, подробно расскажу о самом популярном стандарте токенов JSON Web Tokens и о том, как пользоваться ими в проектах на Python.

More Decks by Python Community Chelyabinsk

Other Decks in Programming

Transcript

  1. Состояние TCP — stateful. Он хранит информацию об открытом соединении

    и переданных данных. HTTP — stateless. Он не обязан хранить информацию между запросами.
  2. Cookies (RFC 2965) Набор пар ключ-значение с ограничениями (по размеру

    и количеству) Сервер устанавливает значения с помощью заголовка Set-Cookie Клиент отправляет весь набор в каждом HTTP- запросе
  3. request.session['count'] += 1 request.session['count'] = 1 Сессии в Django if

    'count' in request.session: else: return HttpResponse('count=%s' % request.session['count'])
  4. Сессии в Django: БД CREATE TABLE "django_session" ( "session_key" varchar(40)

    NOT NULL PRIMARY KEY, "session_data" text NOT NULL, "expire_date" datetime NOT NULL );
  5. Сессии в Django: пользователи По ключу _auth_user_id в сессии хранится

    id пользователя. Данные пользователя извлекаются из БД отдельным запросом.
  6. Пользователь Приложение БД Запрос ID сессии Данные сессии ID пользователя

    Данные пользователя Основная логика обработки запроса Сохранение сесии ОК Ответ на запрос
  7. Проблемы • Можно ли не делать эти запросы к базе?

    • Можно ли аутентифицровать без БД?
  8. Токены без состояния В запросах приходят токены, которые содержат в

    себе всё состояние целиком. Состояние не хранится в БД, поэтому без состояния.
  9. Подпись JWT-токена Не зная секретного ключа, невозможно вычислить подпись. Поэтому

    мы можем быть уверены, что полученный от клиента токен подлинный.
  10. Шифрование JWT-токенов Симметричное — один ключ, чтобы зашифровать и расшифровать.

    Асимметричное — шифруем приватным ключом, расшифровываем публичным ключом.
  11. HTTP-заголовки вместо кук Токены обычно вместо кук хранятся в localStorage,

    а передаются в заголовках. Плюсы: • Нет ограничения по размеру • Нет проблемы CSRF
  12. HTTP-заголовки вместо кук Токены обычно вместо кук хранятся в localStorage,

    а передаются в заголовках. Минусы: • Тяжело использовать при серверном рендеринге
  13. JWT в питоне: PyJWT >>> import jwt >>> encoded =

    jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256') 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN8 4AWoo1d7KO1T_yoc0Z6XOpOVswacPZg' >>> jwt.decode(encoded, 'secret', algorithms=['HS256']) {'some': 'payload'}
  14. JWT в питоне: свой велосипед • API handler, который выдает

    токен в обмен на логин и пароль. • Middleware, который читает данные из токена и обогащает ими request.
  15. Пользователь Приложение БД Логин и пароль Проверка данных ОК Токен

    Запрос с токеном Валидация токена Основная логика обработки запроса Ответ на запрос
  16. Продление сессии: пара токенов Access token — токен без состояния,

    действует недолго. Refresh token — токен с состоянием, действует долго, позволяет получить новый access token.
  17. Продление сессии аналогично кукам • Проверяем оставшееся время жизни токена

    на сервере. • Если осталось мало времени, добавляем в ответ сервера заголовок Set-Authorization с новым токеном. • Обновляем токен на клиенте, если ответ содержит этот заголовок.
  18. Отзыв токенов: blacklisting Токены могут хранить уникальный идентификатор в поле

    jti . Эти идентификаторы можно хранить в «черном списке» до тех пор, пока токены не истекут.
  19. Отзыв токенов: смириться Если токены действуют недолго, то пусть они

    продолжают действовать. Но это следует учитывать и проверять действительность токенов в особо важных местах.
  20. Изменение тела В какой-то момент мы захотим добавить в тело

    токена новое поле. Когда сессии лежат в БД, мы можем просто пройтись по ним и обновить данные.
  21. Изменение тела: обратная совместимость Когда мы обновим формат JWT-токена, пользователи

    продолжат присылать старые токены, сохраненные у них в localStorage. Нужно предусмотреть это и корректно обрабатывать эту ситуацию.
  22. Атака с подменой алгоритмов JWT поддерживает алгоритм none , который

    никак не валидирует подпись. Некоторые библиотеки доверяют заголовку токена.
  23. Как происходит атака с подменой алгоритмов 1. Атакующий получает подлинный

    токен. 2. Он декодирует тело токена и меняет свои данные. 3. В заголовке он заменяет HS256 на none . 4. Собрав полученный токен, он отправляет его на сервер.
  24. Совет напоследок Попробуйте использовать JWT или аналоги в качестве одноразовых

    токенов для подтверждения почты, смены пароля или отписки от рассылок. Это гораздо удобнее, чем генерировать и хранить случайные значения.
  25. Ссылки • Как работают сессии в Django • Официальный сайт

    JWT • Лучшие практики для JWT • PyJWT • Критические уязвимости в библиотеках • Не используйте JWT