flask-security can't work with gunicorn with multiple workers?

2.2k Views Asked by At

I'm writing a website with Flask. I use Flask-Secuirty to do authentication. I use nginx + gunicorn to deploy it.

The configuration of nginx as follow:

server{
    listen 80;
    server_name project.example.com;
    location / {
        proxy_pass http://127.0.0.1:5000;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    }
}

And I use gunicorn -w worker_number -k gevent run:app -p app.pid -b 127.0.0.1:5000 to start gunicorn.

If the worker_number is 1, everything is ok.

If the worker_number is greater than 1 like 3, I can't login in with Flask-Security.

The output of server said the post request of login is 200. But the server redirect me to login page again.

After some search, I can't find direct reason of this. And I guess this might cause by SERVER_NAME config of Flask or the misuse of Flask-SQLAlchemy.

Is there anyone has met this situation before? Please give me some advices.

3

There are 3 best solutions below

0
On

I met a similar problem with flask_login, when the worker_number is greater than 1, I could not login in.

My app.secret_key was set to os.urandom(24), so every worker will have another secret key.

Set app.secret_key to a string solved my problem.

0
On

Use something like Flask-Session and use Redis as a session store. I'm not sure how Flask-Security works, but I assume it relies on Flask sessions, in which case it would solve the problem of a user session switching between application servers.

1
On

Just use a fixed secret key.
Generate with following command.
$ openssl rand -base64 <desired_length>

If you don't want to hardcode the key inside source code which you shouldn't for security purposes.
Set up an environment variable and get it.

import os

# -- snip --

app.config["SECRET_KEY"] = os.environ.get("FLASK_APP_SECRET_KEY")