pythonitsdangerous

Unsupported operand type(s) when using URLSafeTimedSerializer.dumps from itsdangerous


I'm having a problem to initiate a serializer in my Flask project

>>> from itsdangerous.url_safe import URLSafeTimedSerializer as Serializer
>>> s = Serializer ('secret', 30)
>>> token = s.dumps({'user_id': 1}).decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\Dell\flaskapp1\v_env1\Lib\site-packages\itsdangerous\serializer.py", line 208, in dumps
    rv = self.make_signer(salt).sign(payload)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Dell\flaskapp1\v_env1\Lib\site-packages\itsdangerous\timed.py", line 55, in sign
    return value + sep + self.get_signature(value)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Dell\flaskapp1\v_env1\Lib\site-packages\itsdangerous\signer.py", line 209, in get_signature
    key = self.derive_key()
          ^^^^^^^^^^^^^^^^^
  File "C:\Users\Dell\flaskapp1\v_env1\Lib\site-packages\itsdangerous\signer.py", line 195, in derive_key
    bytes, self.digest_method(self.salt + b"signer" + secret_key).digest()
                              ~~~~~~~~~~^~~~~~~~~~~
TypeError: unsupported operand type(s) for +: 'int' and 'bytes'
>>>

I have " itsdangerous 2.1.2 version" package

I've tried using code blocks from 2.1.2 itsdangerous version but it throws me a type error in my VScode, that auth_s is not defined, can anyone share any example of itsdangerous 2.1.2 version how to use it in terminal and in VScode, and I tried to install older versions of itsdangerous but it didn't work.


Solution

  • The problem is the 30 that you used when initializing URLSafeSerializer. That class extends Serializer, which expects either a string or bytes object as the second positional argument, not an integer.

    If the second argument is omitted, we can see that the dumps method works:

    >>> from itsdangerous.url_safe import URLSafeTimedSerializer as Serializer
    
    >>> s = Serializer('secret')
    
    >>> s.dumps({'user_id': 1})
    'eyJ1c2VyX2lkIjoxfQ.Y8xp3Q._-IXXynGmlMJvap8JneX2WJvMzY'
    

    Note: The .decode('utf-8') is not necessary here - dumps already returns a string. If, for some reason, you needed bytes instead, then you would need .encode('utf-8') instead.

    Disclaimer: I cannot comment on the security of this solution - this answer is purely making the code that you presented work, and I don't know how secure the defaults are here or when they should / shouldn't be used.