0

I was following some django rest framework tutorials and found some obscure codes. This snippet is from the customised user model, the project from which uses jwt for authentication.

As I commented in the snippet, I can't notice the reason Why they first encodes data and decode it again. I thought this kind of pattern is not only specific to this tutorial, but quite a general pattern. Could anyone explain me please?

 def _generate_jwt_token(self):
        """
        Generates a JSON Web Token that stores this user's ID and 
        has an expiry date set to 60 days into the future.
        """
        dt = datetime.now() + timedelta(days=60)


        token = jwt.encode({ #first encode here
            'id': self.pk,
            'exp': int(dt.strftime('%s'))
        }, settings.SECRET_KEY, algorithm='HS256')

        return token.decode('utf-8') #returns decoded object
Now.Zero
  • 1,147
  • 1
  • 12
  • 23

1 Answers1

1

“Encoding” usually refers to converting data to its binary representation (bytes).

JWT (JSON Web Token) encoding uses a specific data structure and cryptographic signing to allow secure, authenticated exchanges.

The steps to encode data as JWT are as follows :

  1. The payload is converted to json and encoded using base64.
  2. A header, specifying the token type (eg. jwt) and the signature algorithm to use (eg. HS256), is encoded similarly.
  3. A signature is derived from your private key and the two previous values.
  4. Result is obtained by joining header, payload and signature with dots. The output is a binary string.

More informations here.

Decoding it using UTF-8 transforms this binary string into an Unicode string :

>>> encoded_bin = jwt.encode({'some': 'data'}, 'secret_sig', algorithm='HS256')
>>> type(encoded_bin)
<class 'bytes'>

>>> encoded_string = encoded_bin.decode('utf-8')
>>> type(encoded_string)
<class 'str'>

Notes:

  • It is not always possible to decode bytes to string. Base64-encoding your data allows you to store any bytes as a text representation, but the encoded form requires more space (+33%) than it's raw representation.

  • A binary string is prefixed by a b in your Python interpreter (eg. b"a binary string")

Rémi Héneault
  • 383
  • 3
  • 12
  • 1
    Please correct your answer. Encoding and encrypting are two different things! Nothing get's encrypted here. The header and payload of a JWT/JWS are only base64url encoded and the signature is a hash, that also no encryption. – jps Jan 08 '19 at 06:24
  • @jps Edited. I didn't know about jwt, I assumed wrongly looking a the code provided by the author. Thanks – Rémi Héneault Jan 08 '19 at 06:58
  • I don't see 'encryption' mentioned in the question. Your edit is also not correct. The signature is not a hash of the secret key, but a hash of header and payload. You should only answer, when you know the subject. – jps Jan 08 '19 at 07:13