I would honestly question if you actually need JWT anyways.
jwt is useful for independently verified auth tokens. i.e. service a auths the user, generates a token that says '
this is definitely my user with this data'. service b can't auth the user because it has not access to the data, but can trust the jwt from service a.
every time i've seen someone with a jwt issue in django, they've just been wrapping the session id from django in a jwt, and then unwrapping it and verifying it in the db anyways.
I've read plenty about the limitations and security risks of JWT so I'll take the criticism in that sense. However I've implemented them a really hardened way (http-only cookies, not storing anything in localStorage, short token lives, revokable refresh tokens, etc.) so I'm pretty sure it'll be fine.
The thing is, I looked into other auth alternatives (sessions, regular tokens) for Django DRF + React and they all seemed just as difficult to implement. That's the sticking point in this whole discussion and what these guys are trying to solve - auth is critical and sensitive, but it's also largely a commodity that in most cases is not relevant to the application business logic, and there's no reason it should take so long to implement every. single. time.
(But if you have a tip on how to implement auth in Django + SPA's in a super-easy way that scales horizontally and allows users to stay logged in between sessions, I'm willing to be persuaded that the developer experience for auth doesn't suck so much)
I'm definitely not questions if your doing things securely or not. Just if maybe needlessly complex.
I'll describe what i'm doing, as the code is kind of old.
* I have a token model that stores a uuid and the relevant user and data, along with an expiration. This isn't session data, just the valid token. You can also store this in redis or wherever.
* There is an endpoint that takes a username and password, and if valid, generates a token, and sets the token's id as a httpOnly secure cookie. This can also returns basic user data for display, name profilephotourl, global permissions, etc. This has a noauth decorator from DRF
* there is a check token endpoint which just returns the above data. This also updates the expiration.
* i have auth module based on rest_framework.authentication.BaseAuthentication that checks the cookie, token validity, etc and generates a valid user.
We're talking about simplicity, but the solution you outline sounds to me at least as complex as what I implemented, if not more...
I installed two popular libs, tweaked some code in the back, rolled out my front-end, and came up with a robust solution. In my opinion, I wouldn't have saved any time implementing your proposed design if I understand it correctly (especially on the front-end), and I'm not sure about its overall robustness since I don't like at all the idea of periodically polling from the front-end to check the state of the token, as opposed to automatically attempting a refresh on certain response conditions. But that's just me...
Regardless, my original point is that one shouldn't be spending much time at all on a commodity feature like this. I wish I could've spent 80% of that time writing real business logic and interfaces.
> I'm really not sure that a refresh token on the front end actually provides that much security.
Compared to any other mechanism where tokens are revokable (ex: hitting the db), no, it doesn't provide additional security.
Compared to non-revokable tokens it provides loads of additional security, without compromising on UX... The refresh token allows for short access token lifetimes (I have them at ~5min, same as Google has on Firebase), while providing the possibility of keeping the user logged in for weeks and having a revokation mechanism if it all goes south.
jwt is useful for independently verified auth tokens. i.e. service a auths the user, generates a token that says ' this is definitely my user with this data'. service b can't auth the user because it has not access to the data, but can trust the jwt from service a.
every time i've seen someone with a jwt issue in django, they've just been wrapping the session id from django in a jwt, and then unwrapping it and verifying it in the db anyways.