Расскажу как делал я.
Создаём пару refresh_token и access_token и сохраняем в БД.
{
refresh_token: XXX,
access_token: YYY,
user_id: ZZZ,
client_id: A,
}
Отправляем оба клиенту.
Для запросов используется access_token, он содержит нужную инфу о юзере и в БД лезть не заставляет.
Чтобы получить новую пару, используем refresh_token. Старую пару при этом можно удалить, чтобы не раздувать БД.
Остаётся проблема с тем, как заблокировать access_token.
Я использую Redis для хранения списка заблокированных токенов, при этом хранятся они не больше времени жизни токена.
Итого:
Авторизациям > запрос к БД > получили токены
Запрос с токеном > проверка на отсутствие в Redis > расшифровка токена
.... через 60 минут (или другое время жизни токена)
Запрос на обновление токена > запрос к БД > новые токены > запись в Redis
Такая схема позволяет авторизоваться на нескольких устройствах сразу, управлять своими авторизациями (выйти со всех устройств, выйти с устройств А и В).