Skip to content

Commit 0c0b31a

Browse files
doronhorwitzdavidism
authored andcommitted
get_cookie_name in SessionInterface for easier overriding in SecureCookieSessionInterface
1 parent 4bceecc commit 0c0b31a

File tree

3 files changed

+73
-5
lines changed

3 files changed

+73
-5
lines changed

CHANGES.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
.. currentmodule:: flask
22

3+
Version 2.0.0
4+
-------------
5+
6+
Unreleased
7+
8+
- Add :meth:`sessions.SessionInterface.get_cookie_name` to allow
9+
setting the session cookie name dynamically. :pr:`3369`
10+
11+
312
Version 1.1.2
413
-------------
514

src/flask/sessions.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ def is_null_session(self, obj):
173173
"""
174174
return isinstance(obj, self.null_session_class)
175175

176+
def get_cookie_name(self, app):
177+
"""Returns the name of the session cookie.
178+
179+
Uses ``app.session_cookie_name`` which is set to ``SESSION_COOKIE_NAME``
180+
"""
181+
return app.session_cookie_name
182+
176183
def get_cookie_domain(self, app):
177184
"""Returns the domain that should be set for the session cookie.
178185
@@ -340,7 +347,7 @@ def open_session(self, app, request):
340347
s = self.get_signing_serializer(app)
341348
if s is None:
342349
return None
343-
val = request.cookies.get(app.session_cookie_name)
350+
val = request.cookies.get(self.get_cookie_name(app))
344351
if not val:
345352
return self.session_class()
346353
max_age = total_seconds(app.permanent_session_lifetime)
@@ -351,16 +358,15 @@ def open_session(self, app, request):
351358
return self.session_class()
352359

353360
def save_session(self, app, session, response):
361+
name = self.get_cookie_name(app)
354362
domain = self.get_cookie_domain(app)
355363
path = self.get_cookie_path(app)
356364

357365
# If the session is modified to be empty, remove the cookie.
358366
# If the session is empty, return without setting the cookie.
359367
if not session:
360368
if session.modified:
361-
response.delete_cookie(
362-
app.session_cookie_name, domain=domain, path=path
363-
)
369+
response.delete_cookie(name, domain=domain, path=path)
364370

365371
return
366372

@@ -377,7 +383,7 @@ def save_session(self, app, session, response):
377383
expires = self.get_expiration_time(app, session)
378384
val = self.get_signing_serializer(app).dumps(dict(session))
379385
response.set_cookie(
380-
app.session_cookie_name,
386+
name,
381387
val,
382388
expires=expires,
383389
httponly=httponly,

tests/test_reqctx.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import pytest
1212

1313
import flask
14+
from flask.sessions import SecureCookieSessionInterface
1415
from flask.sessions import SessionInterface
1516

1617
try:
@@ -229,6 +230,58 @@ def index():
229230
assert not flask.current_app
230231

231232

233+
def test_session_dynamic_cookie_name():
234+
235+
# This session interface will use a cookie with a different name if the
236+
# requested url ends with the string "dynamic_cookie"
237+
class PathAwareSessionInterface(SecureCookieSessionInterface):
238+
def get_cookie_name(self, app):
239+
if flask.request.url.endswith("dynamic_cookie"):
240+
return "dynamic_cookie_name"
241+
else:
242+
return super(PathAwareSessionInterface, self).get_cookie_name(app)
243+
244+
class CustomFlask(flask.Flask):
245+
session_interface = PathAwareSessionInterface()
246+
247+
app = CustomFlask(__name__)
248+
app.secret_key = "secret_key"
249+
250+
@app.route("/set", methods=["POST"])
251+
def set():
252+
flask.session["value"] = flask.request.form["value"]
253+
return "value set"
254+
255+
@app.route("/get")
256+
def get():
257+
v = flask.session.get("value", "None")
258+
return v
259+
260+
@app.route("/set_dynamic_cookie", methods=["POST"])
261+
def set_dynamic_cookie():
262+
flask.session["value"] = flask.request.form["value"]
263+
return "value set"
264+
265+
@app.route("/get_dynamic_cookie")
266+
def get_dynamic_cookie():
267+
v = flask.session.get("value", "None")
268+
return v
269+
270+
test_client = app.test_client()
271+
272+
# first set the cookie in both /set urls but each with a different value
273+
assert test_client.post("/set", data={"value": "42"}).data == b"value set"
274+
assert (
275+
test_client.post("/set_dynamic_cookie", data={"value": "616"}).data
276+
== b"value set"
277+
)
278+
279+
# now check that the relevant values come back - meaning that different
280+
# cookies are being used for the urls that end with "dynamic cookie"
281+
assert test_client.get("/get").data == b"42"
282+
assert test_client.get("/get_dynamic_cookie").data == b"616"
283+
284+
232285
def test_bad_environ_raises_bad_request():
233286
app = flask.Flask(__name__)
234287

0 commit comments

Comments
 (0)