A Session interface that uses cookies as storage. This will store the data on the cookie in plain text, but with a signature to prevent modification.
| 125 | |
| 126 | |
| 127 | class SecureCookieSessionInterface(SessionInterface): |
| 128 | """A Session interface that uses cookies as storage. |
| 129 | |
| 130 | This will store the data on the cookie in plain text, but with a |
| 131 | signature to prevent modification. |
| 132 | """ |
| 133 | |
| 134 | digest_method = staticmethod(hashlib.sha1) |
| 135 | key_derivation = "hmac" |
| 136 | salt = "cookie-session" |
| 137 | serializer = session_json_serializer |
| 138 | session_class = SecureCookieSession |
| 139 | |
| 140 | def get_signing_serializer(self, app: Quart) -> URLSafeTimedSerializer | None: |
| 141 | """Return a serializer for the session that also signs data. |
| 142 | |
| 143 | This will return None if the app is not configured for secrets. |
| 144 | """ |
| 145 | if not app.secret_key: |
| 146 | return None |
| 147 | |
| 148 | options = { |
| 149 | "key_derivation": self.key_derivation, |
| 150 | "digest_method": self.digest_method, |
| 151 | } |
| 152 | return URLSafeTimedSerializer( |
| 153 | app.secret_key, |
| 154 | salt=self.salt, |
| 155 | serializer=self.serializer, |
| 156 | signer_kwargs=options, |
| 157 | ) |
| 158 | |
| 159 | async def open_session( |
| 160 | self, app: Quart, request: BaseRequestWebsocket |
| 161 | ) -> SecureCookieSession | None: |
| 162 | """Open a secure cookie based session. |
| 163 | |
| 164 | This will return None if a signing serializer is not available, |
| 165 | usually if the config SECRET_KEY is not set. |
| 166 | """ |
| 167 | signer = self.get_signing_serializer(app) |
| 168 | if signer is None: |
| 169 | return None |
| 170 | |
| 171 | cookie = request.cookies.get(self.get_cookie_name(app)) |
| 172 | if cookie is None: |
| 173 | return self.session_class() |
| 174 | max_age = int(app.permanent_session_lifetime.total_seconds()) |
| 175 | try: |
| 176 | data = signer.loads(cookie, max_age=max_age) |
| 177 | return self.session_class(data) |
| 178 | except BadSignature: |
| 179 | return self.session_class() |
| 180 | |
| 181 | async def save_session( |
| 182 | self, |
| 183 | app: Quart, |
| 184 | session: SessionMixin, |
no outgoing calls
searching dependent graphs…