Django login stops working randomly - django

Env:
Django 1.42
Nginx
Gunicorn + gevent
HTTPS
Session storage is default
For some reason login stops working without any reason for some clients on different OS/browsers. Auth is passing, but after redirect user.is_authenticated is False again.
I think, the problem is unrelated to client.
Any ideas why?

It sounds like Django user sessions are getting messed up somehow. Try switching your session engine and make sure your session engine is not running off of a dummy caching backend. If it is running off of a caching engine, make sure your cache isn't being restarted/flushed somehow. Lastly, try using a cookie session backend.

Related

How to solve ERR_TOO_MANY_REDIRECT when deploying django rest framework web app to Azure?

I deployed an web app which django restframework base on Heroku and Azure.
Same app on Heroku works fine.
But when I access to Azure, it causes ERR_TOO_MANY_REDIRECT error.
I googled and found that turn SECURE_SSL_REDIRECT off solved ERR_TOO_MANY_REDIRECT error.
However, it causes 403 CSRF error instead.
I need to find another way to fix ERR_TOO_MANY_REDIRECT or find a way to fix 403 CSRF error.
Can anyone help me to solve this issue?
If your app is on "Azure App Service", the HTTPS connection will be terminated before it reaches your web worker. Your app wil see an incoming HTTP request instead. In this case you need to set SECURE_SSL_REDIRECT = False indeed. If you want to enforce HTTPS (which is a good practice) you can do so in the Azure settings: https://learn.microsoft.com/en-us/azure/app-service/configure-ssl-bindings#enforce-https
About the CSRF-related error: because Azure translates HTTPS to HTTP, you need to configure Django to allow POST requests from a different scheme (since Django 4.0) by adding this to settings.py:
CSRF_TRUSTED_ORIGINS = ["https://YOUR-DOMAIN.com", "https://www.YOUR-DOMAIN.com"]
If this does not solve your problem, you can temporarily set DEBUG = True in production and try again. On the error page, you will see a "Reason given for failure" that you can post here.

CSRF Token Error when using gunicorn and Flask

I've developed a web app that includes the functionality for users to log in and signup. I've done everything as per documentation and tutorials, and everything works fine with the flask server.
The issue is: I use gunicorn and start a web server, open the address (localhost:8000) on few different browsers (Brave and Firefox on Linux, and Brave on Android), I can only log in (Single or multiple different users) from only one client. When I try to do so from another one, it throws 400 Bad Request (CSRF Session token missing or CSRF Session tokens do no match).
Now, this doesn't happen when using Flasks Server. It only happens while using gunicorn.
I've deployed the application to Heroku (Using the Free plan), and I want multiple users to sign in at the same time. This happens on all of the other forms my app has.
All environment variables, secret keys are correctly configured, everything works as intended when using Flask Server. Using Gunicorn doesn't cause any other issues except this. Sometimes, logging in from a single client doesn't work too.
Any help would be appreciated. I've already looked at other threads/questions that were related, but they didn't mention the problem I have
Sorry for the late reply (Maybe it can help someone in the future)
The short answer :
use :
with app.app_context():
your code
instead of :
app.app_context().push()
which is never closed
The long answer :
I guess you use Flask-WTF for managing CSRF,
If yes, there is an if bloc (https://github.com/wtforms/flask-wtf/blob/0.15.x/src/flask_wtf/csrf.py#L53) in the generate_csrf function, which check the flask g variable before generating a new CSRF token. It works perfectly, but when the g variable doesn't reinitilize on each new request (see below for the cause) it creates a conflict between the different users trying to log in.
The principal cause of not reinitilizing the flask g variable is an app context which is pushed manually (usually by : app.app_context().push()) but not closed, in this case the app context is never torn down see : Flask app.teardown_appcontext not being called when DEBUG is false
Finally, i think there is something in the flask DEBUG mode, which force tearing down the app context and reinitilize the g variable.

Cookies when using separate Dyno for react frontend and Django backend

I am building a simple web app using React.js for the frontend and Django for the server side.
Thus frontend.herokuapp.com and backend.herokuapp.com.
When I attempt to make calls to my API through the react app the cookie that was received from the API is not sent with the requests.
I had expected that I would be able to support this configuration without having to do anything special since all server-side requests would (I thought) be made by the JS client app directly to the backend process with their authentication cookies attached.
In an attempt to find a solution that I thought would work I attempted to set
SESSION_COOKIE_DOMAIN = "herokuapp.com"
Which while less than ideal (as herokuapp.com is a vast domain) in Production would seem to be quite safe as they would then be on api.myapp.com and www.myapp.com.
However, with this value set in settings.py I get an AuthStateMissing when hitting my /oauth/complete/linkedin-oauth2/ endpoint.
Searching google for AuthStateMissing SESSION_COOKIE_DOMAIN yields one solitary result which implies that the issue was reported as a bug in Django social auth and has since been closed without further commentary.
Any light anyone could throw would be very much appreciated.
I ran into the exact same problem while using herokuapp.com.
I even posted a question on SO here.
According to Heroku documentation:
In other words, in browsers that support the functionality, applications in the herokuapp.com domain are prevented from setting cookies for *.herokuapp.com
Heroku blocks cookies from frontend.herokuapp.com and backend.herokuapp.com
You need to add a custom domain to frontend.herokuapp.com and backend.herokuapp.com
The entire answer https://stackoverflow.com/a/54513216/1501643

Twitter API returns callback to '127.0.0.1:8001' on production server. Why?

Everything is working on my site, except when I'm trying to log in with twitter through python-social-auth. It worked well on my local development server, but when I went into production, after the twitter login, it sends the response to http://127.0.0.1:8001/complete/twitter.....
I am using gunicorn+nginx without too much knowledge about it, except that i've used it for other projects without problems. Although, I have binded gunicorn --bind 127.0.0.1:8001. Is that the problem? I tried using --bind mydomain.com:8001 but that gives me a 502 Bad Gateway response.

Rack/Sinatra session breaking when deployed on heroku - E13

I have a basic Sinatra app deployed to Heroku. I have 'enable :sessions' in the app and nothing else do do with sessions except setting/accessing the sessions data. The app works well, but if I have a browser session open, and re-deploy to heroku, then when I use the same browser session, I get "Error H13 (Connection closed without response)" and a Application Error in the browser. I can't find out anything more about the error.
If I delete cookies for the domain, then the app starts working again.
so, again, it's: 1) Deploy app, use app in new browser session, all is well. 2) 'git push heroku master' 3) use same browser, E13
tried setting the Rack::Session::Cookie secret explicity but it makes no difference.
Have also run the app in production mode locally, but can't replicate this.
I'd rather not ruin anybody's day if they happen to be using the app when I do a deploy. Any ideas where else to look to track this down?
You need to set the session secret as well:
configure do
enable :sessions
set :session_secret, ENV['SESSION_SECRET'] ||= 'super secret'
end
This was a Rack 1.4.0 bug concerning the way invalid session digests were handled. github.com/rack/rack/issues/299 problem was solved by upgrade to Rack 1.4.1