Wystawianie JWT na świat jako mechanizm do obsługi sesji to moim (i nie tylko moim) zdaniem zły pomysł. Przykładowy post wyjaśniający problemy z używaniem JWT dla sesji jest tutaj: http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/
Argument z tym, że w JWT można zmieścić jakieś dane oprócz ID sesji jest słaby, bo te informacje można przechowywać po stronie serwera, upraszczając (np łatwiej modyfikować dane w Key-Value Store niż w zdalnym tokenie) i oszczędzając transfer między klientem, a serwerem. Skalowalność też łatwo ogarnąć po stronie serwera - to co trzymałbyś w JWT trzymaj w jakimś skalowalnym Key-Value Store np Redis (który ma opcję zapisu danych na dysk z niewielkim lagiem).
Pewną hybrydą klasycznych ciastek i JWT jest trzymanie JWT w ciastku. W tym rozwiązaniu mechanizm ciastek zapewnia bezpieczeństwo, a JWT standaryzuje format zapisu danych w ciastku. Jeśli takie coś jest wymuszone przez framework to można się ograniczyć do trzymania minimalnego zbioru danych w JWT, czyli przede wszystkim numeru sesji.
JWT są natomiast spoko na backendzie (np w komunikacji między mikroserwisami albo instancjami aplikacji w klastrze) jeżeli ich nigdzie nie przechowujemy tylko na bieżąco generujemy (podczas wysyłania żądania HTTP) i weryfikujemy (podczas obsługi żądania HTTP). Innymi słowy: wtedy gdy są jednorazowego użytku. Gdy mamy JWT wielorazowego użytku (access token, refresh token, cokolwiek) to pojawiają się problemy opisane w artykule, który podlinkowałem na początku posta.