Голый JWT не подразумевает хранение токена на сервере. По сути сам JWT и является "хранилищем", которому можно доверять.
Другой вопрос, что использовать голый JWT - как минимум глупо. В игрушечных пет проектах можете не заметить этого, а вот в реальных проектах почти на любой запрос нужно триггерить запросы к хранилищу, не важно что это: какой-то кеш по типу Redis или СУБД MySQL, PostgreSQL, MongoDB и т. д. Это как минимум получение актуальных данных о пользователе для отображения в хедере или еще где, проверка на существование аккаунта и т. д.
Представьте ситуацию, что юзер в вашем блоге пишет гневные комментарии, вы удалили его аккаунт, а он все еще может писать комментарии, только потому, что вы кроме JWT ничего не проверяете.
Именно поэтому сам JWT технология очень сомнительная, он работает только в сферическом вакууме с единорогами в комплекте. В реальности же почти на каждый запрос все равно приходится ходить в базу, кеш, еще куда-то.
Аутентификация это то, что нельзя переизобрести. По факту ее можно сделать как угодно: с двумя токенами (access, refresh), с одним токеном (это уже какие-то сессии получаются). Можно хранить токены в базе, можно в кеше. В общем все это один хер, только в профиль. Сама суть не поменяется никак. Конечно же, при реализации механизма аутентификации нужно учитывать все возможные угрозы. Такие как, угон токена/токенов, CSRF и все прочее.