# Development - hardcoded (NOT for production!)app.secret_key = 'dev-secret-key-change-in-production'# Production - from environmentimport osapp.secret_key = os.environ.get('SECRET_KEY')# Production - from config fileapp.config.from_object('config.ProductionConfig')# Generate a good secret keyimport secretsprint(secrets.token_hex(32)) # Use this in production
Never commit secret keys to version control! Use environment variables or config files excluded from git.
From sessions.py:100-271, Flask uses SecureCookieSessionInterface by default:
class SecureCookieSessionInterface(SessionInterface): """The default session interface that stores sessions in signed cookies through the itsdangerous module.""" salt = "cookie-session" digest_method = staticmethod(hashlib.sha1) key_derivation = "hmac" serializer = session_json_serializer session_class = SecureCookieSession
From sessions.py:24-55, sessions implement SessionMixin:
class SessionMixin: permanent = False # Is this a permanent session? modified = True # Has the session been modified? accessed = False # Has the session been accessed? new = False # Is this a new session?
@app.route('/check-session')def check_session(): # Check if session is permanent if session.permanent: print("Permanent session") # Session is automatically marked as modified when changed session['key'] = 'value' # modified = True # Manually mark as modified (for mutable values) session['list'] = [] session['list'].append('item') # This won't trigger modified! session.modified = True # Mark it manually
@app.route('/get')def get_session(): # With default value username = session.get('username', 'guest') # Check if key exists if 'user_id' in session: user_id = session['user_id'] # Iterate keys for key in session: print(f'{key}: {session[key]}') return f'Hello, {username}'
From sessions.py:83-97, when no secret key is set:
class NullSession(SecureCookieSession): """Session used when no secret key is set.""" def _fail(self, *args, **kwargs): raise RuntimeError( "The session is unavailable because no secret " "key was set. Set the secret_key on the " "application to something unique and secret." ) __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail
From sessions.py:46-54 and ctx.py:396-403, sessions track access:
@app.route('/check')def check(): # Simply accessing session marks it as accessed if session: pass # session.accessed = True # This adds Vary: Cookie header to response return 'OK'
@app.route('/cart/add/<int:product_id>')def add_to_cart(product_id): if 'cart' not in session: session['cart'] = [] session['cart'].append(product_id) session.modified = True # Important for lists! flash(f'Added product {product_id} to cart', 'success') return redirect('/products')