Есть много сообщений о JWT, но ни одно из них, похоже, не решило мое замешательство.
В моем текущем проекте (Next.js 14 и Postgres) я пытаюсь создать собственную аутентификацию, чтобы узнать больше о важных концепциях.
В настоящее время, когда пользователь входит в систему, токен доступа сохраняется в файлах cookie (только HTTP). У меня есть промежуточное программное обеспечение, которое проверяет достоверность этого токена, но когда этот токен недействителен или срок его действия истек, я хочу, чтобы мое промежуточное программное обеспечение вызывало API для получения нового токена доступа с токеном обновления.
Сохраняю ли я этот токен обновления в файлах cookie или его можно сохранить в моей базе данных Postgres?
Потому что, если я хочу, чтобы мое промежуточное программное обеспечение вызывало API для получения нового токена доступа, я беру токен обновления и проверяю его достоверность, а затем получаю новый токен доступа.
Я не знаю, как реализовать это с помощью базы данных postgres, потому что не понимаю, как сервер может знать, какой токен обновления пользователя нужно получить из таблицы.
Итак, на самом деле мой вопрос: можно ли просто хранить токен обновления вместе с токеном доступа? Если нет, то как я могу реализовать логику базы данных, потому что я слышал, что токен обновления хорошо хранить на сервере.





Я думаю, что ваш вопрос немного неясен, что выполняется на стороне клиента, а что — на стороне сервера. Я сделаю некоторые предположения.
Прежде всего, клиент должен хранить как ваш токен доступа, так и ваш токен обновления, и оба они должны быть надежно защищены на стороне клиента. См. https://stackoverflow.com/a/76889949/2889165
У вас есть несколько различных вариантов хранения клиентской части токена обновления. Я видел следующее:
Во-вторых, токен обновления может быть либо автономным, например, подписанным JWT, используемым в серверной части без сохранения состояния, либо токен обновления может храниться как на стороне клиента, так и на стороне сервера для серверной части с сохранением состояния.
@manny_paz не стесняйтесь проголосовать и принять ответ. Существует стандарт шифрования JWT, но мы чаще всего только его подписываем. Шифрование токена просто дает вам еще один токен...
Недавно я только что создал учетную запись SO, поэтому могу задавать вопросы и могу только принять. Причина, по которой я зашифровал токен, заключается в том, чтобы добавить еще один уровень безопасности, поскольку, поскольку он находится в файлах cookie, он будет включаться в каждый запрос.
Если вы не храните в JWT что-либо секретное (и я не знаю ни одного случая, когда вам следует это делать), добавление такого типа «запутывания» считается плохой практикой, потому что либо у вас есть что-то водонепроницаемое внизу и оно вам не нужно, или он не водонепроницаем и тогда это не поможет. Кроме того, это не позволяет вам управлять графическим интерфейсом клиента на основе состояния пользователя.
В этом есть смысл. Я думаю, не существует «идеального» способа хранения токена JWT? Я слышал, что это можно сделать несколькими способами: в памяти, локальном хранилище или файлах cookie. Но для каждого есть компромисс. Я хотел, чтобы мой сервер аутентификации оставался без сохранения состояния и не имел никаких сведений о сервере ресурсов. Поэтому сохранение обновления в базе данных было невозможным. Кроме того, аннулирование всех токенов обновления в случае взлома обойдется дорого. Единственная причина, по которой я подумал, что шифрование токена обновления было бы хорошей идеей, заключалась в том, что все запросы будут отправляться с доступом и обновлением с использованием метода cookie. Но конфиденциальной информации нет.
Если произойдет нарушение, вы поменяете закрытый ключ подписи JWT, что немедленно сделает недействительными все JWT, не дожидаясь следующего обновления. А токен обновления — это просто случайная строка, и его шифрование просто создаст новую случайную строку, верно?
Ого... Я никогда об этом не думал. Но означает ли это, что я не могу просто хранить свой закрытый ключ подписи в файле env, но мне он понадобится в переменных env, например, в менеджере секретов aws? Для этого созданы эти системы? Поскольку этот проект является локальным, я просто храню ключ подписи в файле .env.local сервера аутентификации и в файле .env.local сервера ресурсов. И да, токен обновления становится новой случайной строкой.
Нет, мы приступаем к операции. :-) Вы определенно можете хранить ключ в файле на вашем сервере (хотя если у вас есть перерыв, его будет легче найти, чем просто хранить его в памяти). Секретные менеджеры действительно пригодятся, когда у вас нет статического сервера, но вы можете запускать лямбда-функции, контейнеры в Kubernetes и т. д. Также, если у вас 200 разработчиков, тогда только немногие должны иметь доступ к ключу в виде обычного текста.
Проведите анализ рисков. Что произойдет, если клиент будет взломан и JWT украден? (обнаружение, если токен обновления используется дважды или JWT используется с другого IP-адреса и т. д.) Что произойдет, если мой сервер будет скомпрометирован? Сегментирована ли моя сеть или игра со вторжением окончена на всех уровнях? Если вы считаете, что ваш ключ подписи был украден, вам необходимо сдать его на переработку после того, как вы исправите точку входа и избавитесь от всех бэкдоров.
Попался, имеет смысл. Я в основном думал поверхностно, а не об анализе рисков, но это помогает.
Извините, что мой вопрос был немного неясен, но да, вы ответили на мой вопрос! Я пошел по пути хранения токена обновления в файле cookie только для http, но зашифровал его перед сохранением. А для аннулирования токенов обновления я использую Redis. Я посмотрю на хранилище сеансов.