Internal Server Error when using Flask session
According to Flask sessions documentation:
... What this means is that the user could look at the contents of your cookie but not modify it, unless they know the secret key used for signing.
In order to use sessions you have to set a secret key.
Set secret key. And you should return string, not int.
#!/usr/bin/env pythonfrom flask import Flask, sessionapp = Flask(__name__)@app.route('/')def run(): session['tmp'] = 43 return '43'if __name__ == '__main__': app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' app.run()
As @falsetru mentioned, you have to set a secret key.
Before sending the session
cookie to the user's browser, Flask signs the cookies cryptographically, and that doesn't mean that you cannot decode the cookie. I presume that Flask keeps track of the signed cookies, so it can perform it's own 'magic', in order to determine if the cookie that was sent along with the request (request headers), is a valid cookie or not.
Some methods that you may use, all related with Flask class instance, generally defined as app
:
defining the
secret_key
variable forapp
objectapp.secret_key = b'6hc/_gsh,./;2ZZx3c6_s,1//'
using the
config()
methodapp.config['SECRET_KEY'] = b'6hc/_gsh,./;2ZZx3c6_s,1//'
using an external configuration file for the entire Flask application
$ grep pyfile app.pyapp.config.from_pyfile('flask_settings.cfg')$ cat flask_settings.pySECRET_KEY = b'6hc/_gsh,./;2ZZx3c6_s,1//'
Here's an example (an adaptation from this article), focused on providing a more clearer picture of Flask session
cookie, considering the participation of both Client and Server sides:
from flask import Flask, request, session import os app = Flask(__name__) @app.route('/') def f_index(): # Request Headers, sent on every request print("\n\n\n[Client-side]\n", request.headers) if 'visits' in session: # getting value from session dict (Server-side) and incrementing by 1 session['visits'] = session.get('visits') + 1 else: # first visit, generates the key/value pair {"visits":1} session['visits'] = 1 # 'session' cookie tracked from every request sent print("[Server-side]\n", session) return "Total visits:{0}".format(session.get('visits')) if __name__ == "__main__": app.secret_key = os.urandom(24) app.run()
Here's the output:
$ python3 sessions.py * Serving Flask app "sessions" (lazy loading)* Environment: productionWARNING: Do not use the development server in a production environment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)[Client-side]Upgrade-Insecure-Requests: 1Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Connection: keep-aliveHost: 127.0.0.1:5000User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0Accept-Encoding: gzip, deflateAccept-Language: en-US,en;q=0.5[Server-side]<SecureCookieSession {'visits': 1}>127.0.0.1 - - [12/Oct/2018 14:27:05] "GET / HTTP/1.1" 200 -[Client-side]Upgrade-Insecure-Requests: 1Cookie: session=eyJ2aXNpdHMiOjF9.DqKHCQ.MSZ7J-Zicehb6rr8qw43dCVXVNA # <--- session cookieAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Connection: keep-aliveHost: 127.0.0.1:5000User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0Accept-Encoding: gzip, deflateAccept-Language: en-US,en;q=0.5[Server-side]<SecureCookieSession {'visits': 2}>127.0.0.1 - - [12/Oct/2018 14:27:14] "GET / HTTP/1.1" 200 -
You may have noticed that in the example above, I'm using the os
lib and the urandom()
function, in order to generate Flask's secret key, right?
From the official doc:
How to generate good secret keys
A secret key should be as random as possible. Your operating system has ways to generate pretty random data based on a cryptographic random generator. Use the following command to quickly generate a value for Flask.secret_key (or SECRET_KEY):
$ python -c 'import os; print(os.urandom(16))'
b'_5#y2L"F4Q8z\n\xec]/'
PLUS NOTE
As you can see, the creators of Flask support the practice of using
os.urandom()
for building the Flask secret key, from older versions of the tool to its latest version. So: why @joshlsullivan's answer received downvotes (deserves an upvote) and why @MikhailKashkin writes that, usingos.urandom()
is terrible idea, are mysteries.