The default session interface that stores sessions in signed cookies through the :mod:`itsdangerous` module.
| 282 | |
| 283 | |
| 284 | class SecureCookieSessionInterface(SessionInterface): |
| 285 | """The default session interface that stores sessions in signed cookies |
| 286 | through the :mod:`itsdangerous` module. |
| 287 | """ |
| 288 | |
| 289 | #: the salt that should be applied on top of the secret key for the |
| 290 | #: signing of cookie based sessions. |
| 291 | salt = "cookie-session" |
| 292 | #: the hash function to use for the signature. The default is sha1 |
| 293 | digest_method = staticmethod(_lazy_sha1) |
| 294 | #: the name of the itsdangerous supported key derivation. The default |
| 295 | #: is hmac. |
| 296 | key_derivation = "hmac" |
| 297 | #: A python serializer for the payload. The default is a compact |
| 298 | #: JSON derived serializer with support for some extra Python types |
| 299 | #: such as datetime objects or tuples. |
| 300 | serializer = session_json_serializer |
| 301 | session_class = SecureCookieSession |
| 302 | |
| 303 | def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None: |
| 304 | if not app.secret_key: |
| 305 | return None |
| 306 | |
| 307 | keys: list[str | bytes] = [] |
| 308 | |
| 309 | if fallbacks := app.config["SECRET_KEY_FALLBACKS"]: |
| 310 | keys.extend(fallbacks) |
| 311 | |
| 312 | keys.append(app.secret_key) # itsdangerous expects current key at top |
| 313 | return URLSafeTimedSerializer( |
| 314 | keys, # type: ignore[arg-type] |
| 315 | salt=self.salt, |
| 316 | serializer=self.serializer, |
| 317 | signer_kwargs={ |
| 318 | "key_derivation": self.key_derivation, |
| 319 | "digest_method": self.digest_method, |
| 320 | }, |
| 321 | ) |
| 322 | |
| 323 | def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None: |
| 324 | s = self.get_signing_serializer(app) |
| 325 | if s is None: |
| 326 | return None |
| 327 | val = request.cookies.get(self.get_cookie_name(app)) |
| 328 | if not val: |
| 329 | return self.session_class() |
| 330 | max_age = int(app.permanent_session_lifetime.total_seconds()) |
| 331 | try: |
| 332 | data = s.loads(val, max_age=max_age) |
| 333 | return self.session_class(data) |
| 334 | except BadSignature: |
| 335 | return self.session_class() |
| 336 | |
| 337 | def save_session( |
| 338 | self, app: Flask, session: SessionMixin, response: Response |
| 339 | ) -> None: |
| 340 | name = self.get_cookie_name(app) |
| 341 | domain = self.get_cookie_domain(app) |