Python: API de generación de token con su peligroso

Estoy siguiendo el libro “Flask Web Development” para implementar la autenticación basada en token. Básicamente, el usuario se autentica a sí mismo con autenticación básica HTTP y se genera un token para ello:

s = Serializer(app.config['SECRET_KEY'], expires_in = 3600) token = s.dumps({ 'id': user.id }) 

Pero parece que esto no cambia mientras la id y SECRET_KEY permanezcan igual. Entiendo que la transacción será a través de HTTPS, pero aún creo que un token dynamic sería mejor. ¿Cómo lograr un token dynamic?

Si necesita un token que sea sensible al tiempo, use la clase TimedSerializer lugar.

No solo usa una marca de tiempo para formar la firma (lo que produce una nueva firma cada vez que la usa), sino que también puede limitar el tiempo de vida del token utilizando esa marca de tiempo:

 >>> from itsdangerous import TimedSerializer >>> s = TimedSerializer('sekrit') >>> token = s.dumps({'id': 'foobar'}) >>> token '{"id": "foobar"}.COWWsA.dect1vZLaDdgFQUA1G_iTpPY3Hg' >>> s.loads(token, max_age=3600) {'id': 'foobar'} >>> s.loads(token, max_age=0) Traceback (most recent call last): File "", line 1, in  File "/Users/mpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/itsdangerous.py", line 643, in loads .unsign(s, max_age, return_timestamp=True) File "/Users/mpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/itsdangerous.py", line 463, in unsign date_signed=self.timestamp_to_datetime(timestamp)) itsdangerous.SignatureExpired: Signature age 18 > 0 seconds 

Tenga en cuenta que la clase Serializer no admite realmente un argumento de palabra clave expires_in , así que sospecho que el código que está citando realmente usa la clase TimedJSONWebSignatureSerializer (no documentada) (que se importa con un alias), que toma ese argumento de palabra clave, y que incluye un marca de tiempo también:

 >>> from itsdangerous import TimedJSONWebSignatureSerializer as Serializer >>> s = Serializer('sekrit', expires_in=3600) >>> token = s.dumps({'id': 'foobar'}) >>> token 'eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ0MzEwODAyMywiaWF0IjoxNDQzMTA0NDIzfQ.eyJpZCI6ImZvb2JhciJ9.eCD3zKK1lYT8cZ9w8g0YVpaF-1rR-k6UNCYq9dHmvGo' >>> s.loads(token) {'id': 'foobar'} >>> s = Serializer('sekrit', expires_in=0) >>> token = s.dumps({'id': 'foobar'}) >>> token 'eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ0MzEwNDUwMCwiaWF0IjoxNDQzMTA0NTAwfQ.eyJpZCI6ImZvb2JhciJ9.Eiw3Eco7p61X-ikMxXS5dDVmjYmRSThcsMCxMyuA-r0' >>> s.loads(token) Traceback (most recent call last): File "", line 1, in  File "/Users/mpieters/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/itsdangerous.py", line 807, in loads date_signed=self.get_issue_date(header)) itsdangerous.SignatureExpired: Signature expired 

Debido a que la marca de tiempo está incluida, el token generado no es estático:

 >>> s = Serializer('sekrit', expires_in=3600) >>> token1 = s.dumps({'id': 'foobar'}) >>> token2 = s.dumps({'id': 'foobar'}) >>> from difflib import ndiff >>> print '\n'.join(ndiff(token1.split('.'), token2.split('.'))) - eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ0MzEwODIwMywiaWF0IjoxNDQzMTA0NjAzfQ ? ^ ^ ^^ + eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ0MzEwODIxMSwiaWF0IjoxNDQzMTA0NjExfQ ? ^ ^ ^^ eyJpZCI6ImZvb2JhciJ9 - YmrKQTvZEWw4_JOOPn5uEk9QlZNla4o3Gvo09H1MXfM + ApeLrwT_R60pkvCYe4ihzJFPG55tGiJK6VSi6BKxAXM 

Estos dos tokens difieren materialmente a pesar de que fueron producidos por el mismo serializador.