ds_author cookie can now expire, closes #829

Refs https://github.com/simonw/datasette-auth-github/issues/62#issuecomment-642152076
This commit is contained in:
Simon Willison 2020-06-10 12:39:54 -07:00
commit 57e812d5de
9 changed files with 99 additions and 21 deletions

View file

@ -336,11 +336,55 @@ Authentication plugins can set signed ``ds_actor`` cookies themselves like so:
.. code-block:: python
response = Response.redirect("/")
response.set_cookie("ds_actor", datasette.sign({"id": "cleopaws"}, "actor"))
return response
response.set_cookie("ds_actor", datasette.sign({
"a": {
"id": "cleopaws"
}
}, "actor"))
Note that you need to pass ``"actor"`` as the namespace to :ref:`datasette_sign`.
The shape of data encoded in the cookie is as follows::
{
"a": {... actor ...}
}
.. _authentication_ds_actor_expiry:
Including an expiry time
------------------------
``ds_actor`` cookies can optionally include a signed expiry timestamp, after which the cookies will no longer be valid. Authentication plugins may chose to use this mechanism to limit the lifetime of the cookie. For example, if a plugin implements single-sign-on against another source it may decide to set short-lived cookies so that if the user is removed from the SSO system their existing Datasette cookies will stop working shortly afterwards.
To include an expiry, add a ``"e"`` key to the cookie value containing a `base62-encoded integer <https://pypi.org/project/python-baseconv/>`__ representing the timestamp when the cookie should expire. For example, here's how to set a cookie that expires after 24 hours:
.. code-block:: python
import time
import baseconv
expires_at = int(time.time()) + (24 * 60 * 60)
response = Response.redirect("/")
response.set_cookie("ds_actor", datasette.sign({
"a": {
"id": "cleopaws"
},
"e": baseconv.base62.encode(expires_at),
}, "actor"))
The resulting cookie will encode data that looks something like this:
.. code-block:: json
{
"a": {
"id": "cleopaws"
},
"e": "1jjSji"
}
.. _permissions:
Built-in permissions

View file

@ -153,12 +153,12 @@ To set cookies on the response, use the ``response.set_cookie(...)`` method. The
samesite="lax",
):
You can use this with :ref:`datasette.sign() <datasette_sign>` to set signed cookies. Here's how you would set the ``ds_actor`` cookie for use with Datasette :ref:`authentication <authentication>`:
You can use this with :ref:`datasette.sign() <datasette_sign>` to set signed cookies. Here's how you would set the :ref:`ds_actor cookie <authentication_ds_actor>` for use with Datasette :ref:`authentication <authentication>`:
.. code-block:: python
response = Response.redirect("/")
response.set_cookie("ds_actor", datasette.sign({"id": "cleopaws"}, "actor"))
response.set_cookie("ds_actor", datasette.sign({"a": {"id": "cleopaws"}}, "actor"))
return response
.. _internals_datasette: