I just created my production environment for the Flask application that I was developing.
This stack:
Windows Server 2012 R2 Hyper-V VM - Running Ubuntu 14.04 Docker 1.5 - Running Containers: mysql 5.6 nginx 1.6.3 uwsgi 2.0.10
So basically I have a static IP address set in Ubuntu, port 80 is sent to the nginx container, the data volume shared between the nginx and uwsgi containers for the socket file, and finally the connection between the mysql container and uwsgi container for communication with the database.
I used CSRF in the following implementation in my local development environment for a while without any problems:
from flask_wtf import Form class UserForm(Form): ...
And then in my template:
<form> {{ form.hidden_tag() }} ... </form>
However, when I moved my application unchanged to the environment mentioned above, I get:
Invalid request
The CSRF symbol is missing or invalid.
in response when I try to submit the form. I use the exact exact requirements.txt file with the item to configure my Flask application. I also verified that the CSRF token is actually in the HTML page of the page.
Does anyone know why this is happening?
EDIT:
To answer the questions in the comments: The version of Flask-WTF and WTForms is the same in both my docker application container and my local virtual development server. Here is my requirements file, created from my dev environment and used to configure my application in a docker container:
Flask==0.10.1 Flask-Login==0.2.11 Flask-Mail==0.9.1 Flask-Migrate==1.2.0 Flask-MySQL==1.2 Flask-Principal==0.4.0 Flask-SQLAlchemy==2.0 Flask-Script==2.0.5 Flask-Security==1.7.4 Flask-WTF==0.10.2 Flask-WhooshAlchemy==0.55a Jinja2==2.7.3 Mako==1.0.0 MarkupSafe==0.23 PyMySQL==0.6.2 SQLAlchemy==0.7.9 Tempita==0.5.2 WTForms==2.0.1 Werkzeug==0.9.6 Whoosh==2.6.0 alembic==0.6.7 blinker==1.3 chardet==2.2.1 decorator==3.4.0 itsdangerous==0.24 lamson==1.3.4 passlib==1.6.2 py-bcrypt==0.4 pytz==2014.9 sqlalchemy-migrate==0.7.2
As they say, in my container for dockers there are several additional modules due to the installation of uWSGI, as well as my flash application. Here are the additional ones.
argparse (1.2.1) colorama (0.2.5) docutils (0.12) html5lib (0.999) lockfile (0.10.2) mock (1.0.1) MySQL-python (1.2.5) nose (1.3.6) python-daemon (2.0.5) python-modargs (1.7) requests (2.2.1) six (1.5.2) urllib3 (1.7.1) uWSGI (2.0.10) wheel (0.24.0) wsgiref (0.1.2)
Wow, therefore more than a couple. Perhaps I have a conflicting package?
Regarding SECRET_KEY and CSRF_SESSION_KEY: I had SECRET_KEY defined in my config.py. I was lucky that without defining CSRF_SESSION_KEY it would be SECRET_KEY by default. However, I went ahead and defined CSRF_SESSION_KEY, but it didn't seem to make any difference.
Finally, I looked at changing the API from {{form.hidden_tag ()}} to {{form.csrf_token}}. They still have links to both forms in documents for the latest version. On the CSRF page they have the latter, but in quickstart they still have the first. I'm not sure what is connected with this, but to be sure that I implemented the version on the CSRF page as follows:
INIT .py:
from flask_wtf.csrf import CsrfProtect CsrfProtect(app)
user_login.html
<form> {{ form.csrf_token }} ... </form>
But I still get the same answer.
As I said, the Flask-WTF documentation is everywhere. Therefore, I tried to use all kinds of combinations. At the bottom of this page: http://flask-wtf.readthedocs.org/en/latest/csrf.html they refer to the wrong import, so I replaced
from the import form flask_wtf
from
from flask.ext.wtf import form
Still no dice. Thanks for the comments though, gave me more to try!
I also just tried combining everything into one docker container, but I still get the same result.