Как правильно придумать свой велосипед для токенов?
Есть задача реализовать выдачу токена при аутентификации.
Серверная сторона - связка NodeJs и PostgreSQL.
Есть таблица юзеров, в которой есть аттрибуты token и token_life_time.
В данный момент, когда клиент аутентифицируется в системе, он получает токен(этот же токен кладется в базу в поле token данного юзера), и в token_life_time кладется new Date() + 24 часа.
Теперь этот юзер обращается к REST ресурсам с заголовком Authorization: Bearer <сюда кладется наш токен>. Токен из себя представляет просто 90-значную строку произвольных символов. При обращение к ресурсу проверятся жизнь токена(token_life_time). Если текущее время меньше token_life_time, то токен еще актуален и юзер имеет доступ к ресурсам, иначе - нет.
Так вот, это все успешно отрабатывает и все довольны.
Вопрос в следующем.
Сейчас есть проблема с использованием рандомайзера для токена(90 произвольных символов), который никак не защищен криптографически. Более того, хочется не генерить произвольные символы, положить в токен нечто важное, например емеил и саму дату истечения срока жизни токена. Хэширование собираюсь реализовать через bcrypt. Bcrypt умеет делать сверку, однако я не смогу получить из хэша дату истечения срока. Однако, она нужна, так как нужно проверять актуальность токена.
Как быть?
Как минимум: вы должны сверять не просто токен, а сопоставлять токен и сессию пользователя. Иначе ваш велосипед будет уязвим ко всем типам MiTM-атак. Судя по тексту уязвим будет каждые 24 часа - достаточно дождаться авторизации пользователя и после этого можно передать токен атакующему скрипту.
В каком смысле убивать токен? При генерации в jwt попадает дата до какого срока он действует. В базу его записывать не нужно. При аунтификации на строне сервера с просроченным полем действия этого токена клиент не аунтифицируется.
Это ясно, но как сделать logout? Возможно, я что то не понимаю, но суть ведь в том, чтобы завершить сессию. То есть аннулировать валидность токена. А если я это сделаю на клиенте, это не гарантирует прерывание сессии. То есть я через приложение не смогу отправлять запросы, но через любой другой инструмент смогу, к примеру Postman. Это надо делать на сервере.
Это все относится к стратегии аунтификации. Скажем пользователь делает запрос к апи с jwt у которого истек срок действия. В стратегии перед проверкой есть ли такой пользователь внутри системы проверяется поле со сроком действия, если он просрочен то возвращается 401.
sawuer, можно сделать черный список токенов, у которых время жизние еще не окончено, хранить например в redis. Если пользователь выходит, то внести в редис с временем жизни токена и редис потом сам удалит, или наоборот хранить только активные токены