Closed StitiFatah closed 3 years ago
Use the experimental JWT authentication class in your settings file instead: JWTTokenUserAuthentication
As for why the database hits, stateless authentication does not mean don't check if the user is still active. Stateless just means we don't keep the session data on the server side. Stateful authorization is when we store the session data in a cache/database.
Even for session/stateful authorization, it's been raised in Django long ago by BertrandBordage as to why we hit the database to make sure the user still exists: https://code.djangoproject.com/ticket/23011
Hope that clears it up!
Edit:
You should not be using React with SimpleJWT in the production side. Please visit https://github.com/Andrew-Chen-Wang/SPA-with-httponly-sessions You're still supposed to use session/stateful authorization for browsers since you need to set the session data as httpOnly in cookies.
If you use React with this repository, then you most likely set a cookie that isn't httpOnly. That 's a credential stealing risk. I recommend your team use SimpleJWT for local development and Django session middleware for production. Read the README in that repository.
Oh hold on, let me also add the advantages and disadvantages that I missed in that previous comment.
Ok it's confusing because every article I read which compare classic Tokens vs JWT points out that it doesn't need to hit the databsed to confirm the user is logged in
@StitiFatah Edited that initial comment.
Ok it's confusing because every article I read which compare classic Tokens vs JWT points out that it doesn't need to hit the databsed to confirm the user is logged in
I'm assuming you're talking about how 99% of tutorials use this repository when it comes to SPA development. It's an extremely saturated market for tutorials, so I'm not surprised that probably 80% of those tutorials have never actually read the code before. Please only use this repository for local development, and follow that tutorial for production and deployment.
Also:
classic Tokens vs JWT
There is no real difference except for how they are generated. What those tutorials are incorrectly talking about is how (factually true) each repository actually implements these authentication schemas. For example, DRF-JWT (archived) used SlidingToken method to allow you to continuously use one refresh token (dangerous since MITM attacks could happen). The repository uses two tokens and always passes on access/refresh style, like how OpenID Connect does it.
Ok it's confusing because every article I read which compare classic Tokens vs JWT points out that it doesn't need to hit the databsed to confirm the user is logged in
I'm assuming you're talking about how 99% of tutorials use this repository when it comes to SPA development. It's an extremely saturated market for tutorials, so I'm not surprised that probably 80% of those tutorials have never actually read the code before. Please only use this repository for local development, and follow that tutorial for production and deployment.
I'm referring to general talks about JWT not only ones related to django or to this particular library. But ok I'll read the tutorial, it took me some time to make it works with React and avoid infinite loops and stuff like that but if it's truly not recommended I should start again from scratch ( but why don't you say it on the main README ? )
Sorry if this text sounds harsh. The topic of JWT with SPAs is something that keeps popping up that I vehemently dislike due to being a huge security vulnerability. If I sound mean/angry, truly sorry about the language!
Sorry if this text sounds harsh. The topic of JWT with SPAs is something that keeps popping up that I vehemently dislike due to being a huge security vulnerability. If I sound mean/angry, truly sorry about the language!
Don't worry it didn't sound harsh at all, thanks for helping !
I'm referring to general tals about JWT not only ones related to django or to this particular library.
Hm, that's interesting. JWTs is not an authentication method. It's just a token, a format, something that can just be generated. How you use it is up to a package/library.
but why don't you say it on the main README ?
I used to have all the templates in an issue, but it too was trying to replace session authorization for SimpleJWT authorization (which is what you did). So I just restarted and created that aforementioned repository. I can't merge any PRs without a different maintainer (for security purposes), so that's why you don't see it in the README.
We'll add that repository to the README sooner or later.
I should start again from scratch
No! Use SimpleJWT for local development and keep all your code. For PRODUCTION, don't use SimpleJWT. If you need some help, let me know in that repository (since this method is actually no in the repository).
@StitiFatah I've update the README in that repository to be a little more clear regarding directions.
Hm, that's interesting. JWTs is not an authentication method. It's just a token, a format, something that can just be generated. How you use it is up to a package/library.
I should stop reading random articles on the internet and take them too seriously before reading official docs then, i should have learned the lesson while ago
No! Use SimpleJWT for local development and keep all your code. For PRODUCTION, don't use SimpleJWT. If you need some help, let me know in that repository (since this method is actually no in the repository).
OK thanks for your help ! I might take the time to read https://github.com/Andrew-Chen-Wang/SPA-with-httponly-sessions . If I understand well you advice to use SimpleJWT in development ( to take advantage of hot reloading ) and using the old way ( session ) in production by putting the react app in the static files ?
It's my first React SPA and went with JWT to have a clear separation and don't have to worry about connecting react to django through django-webpack-loader or whatever ( If only I knew it'd be way more of a problem lol ) . When I was using Vue that's what i've been doing ( vue dist in static files ) and I got hot reloading without django webpack loader just using this in my vue config
module.exports = {
publicPath: "/static/dist",
outputDir: "../static_in_env/dist",
indexPath: "../../templates/demo/index.html",
// productionSourceMap: false,
filenameHashing: false,
// Django will hash the files for us, not webpack
configureWebpack: {
output: {
chunkFilename: "[id]-[chunkhash].js",
// DO allow webpack to hash chunks.
},
},
devServer: {
writeToDisk: true,
// Write files to disk in dev mode, so Django can serve the assets
},
};
Yes, you are correct.
django-webpack-loader
Originally, that repository was kinda like a copy of webpack loader, just much smaller. But the new README suggests you don't use web pack at all.
When I was using Vue that's what i've been doing ( vue dist in static files ) and I got hot reloading without django webpack loader just using this in my vue config
Unfortunately, I'm not much of a JS developer haha. But I actually don't quite understand this. But from your description, it sounds like what you did before was mostly correct? Sorry still don't know much about SPA development itself. I think my repository was just providing a way to deploy your static files to GitHub pages as a CDN (and the same action if you deploy the built HTML from your JS repository to your Django repository).
Yes, you are correct.
django-webpack-loader
Originally, that repository was kinda like a copy of webpack loader, just much smaller. But the new README suggests you don't use web pack at all.
When I was using Vue that's what i've been doing ( vue dist in static files ) and I got hot reloading without django webpack loader just using this in my vue config
Unfortunately, I'm not much of a JS developer haha. But I actually don't quite understand this. But from your description, it sounds like what you did before was mostly correct? Sorry still don't know much about SPA development itself. I think my repository was just providing a way to deploy your static files to GitHub pages as a CDN (and the same action if you deploy the built HTML from your JS repository to your Django repository).
Yes it was fine with Vue. Thanks for your time and clarifications , I'll point out this issue in my topic on r/django and will surely check your repo !
Was using dj-rest-auth
which support simplejwt.
Each request (even empty ones) took at least 85-125ms because of that query.
Decided to rewrite dj-rest-auth's auth module to use the experimental's one.
Now it's 5 times faster.
However, on views, request.user obviously doesn't return the object but only the token which has id key (user key id)
For PRODUCTION, don't use SimpleJWT
Uhm, can we please elaborate on this statement? I don't see anything in the readme or the docs that says "this module is only for development, never use in prod" - To find this sort of slapped willy-nilly in a comment is jarring at the least.
For PRODUCTION, don't use SimpleJWT
Uhm, can we please elaborate on this statement? I don't see anything in the readme or the docs that says "this module is only for development, never use in prod" - To find this sort of slapped willy-nilly in a comment is jarring at the least.
It's an opinion of mine that if you're using an SPA with SimpleJWT, my opinion is to switch to using sessions. People have used SimpleJWT successfully with an SPA, but with the influx of tutorials, I've mostly left this out of any docs.
There's a years long PR that is implemented in dj-rest-auth that helps and uses simplejwt, so most have gone there
Interesting, so in your opinion this is better than using just SimpleJWT with the blacklist app and short lived tokens?
Yes, using sessions is much better. Instagram still does it to this day.
Hi and thanks in advance,
I've successfully setup JWT authentication using django-rest-framework-simplejwt and React but I'm still very confused about the advantages and specifically database hits. I'm using simplejwt with
ROTATE_REFRESH_TOKENS': True 'BLACKLIST_AFTER_ROTATION': True
, when my access_token expire I ask for a new one through /api/token/refresh and it blacklist old tokens, I'm using axios interceptors to perform that automatically.But in my understanding the benefits of JWt is that they are stateless, meaning I don't have to hit the user database table everytime I want to make an a request that needs authentication permission. The problem is even with a simple view like this :
using django-silk I see that it still performs 1 query to my user table when my access token is valid , is that normal ? I'm really confused.
Here are django silk outputs screen1 screen2 screen3 screen4
Isn't get_user from https://github.com/SimpleJWT/django-rest-framework-simplejwt/blob/master/rest_framework_simplejwt/authentication.py hiting the user object everytime ?
I've already asked the question on reddit and SO and they advised me to remove AuthMiddleware, so I removed both
'django.middleware.csrf.CsrfViewMiddleware'
and'django.contrib.auth.middleware.AuthenticationMiddleware'
but I still get the same result. Setting permissions_classes to AllowAny doesn't vhange anything either.That's my axios code if needed :
( I know I shouldn't use localStorage but whatever )
and I would typically just call this function to make the simple request to the view written above :