1

How can I remove the dictionary value "typ": "JWT" from jwt header? I have tried the following

jwt.encode(
    {
        "iat": 1588108543,
        "exp": 1588112143,
        "ehts": "...",
        "edts": "...."
    },
    privateKey,
    algorithm='RS256',
    headers={"alg": "RS256"})

but still getting typ in jwt header. I am using pyjwt python library.

Output:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODgxMDg1NDMsImV4cCI6MTU4ODExMjE0MywiZWh0cyI6ImNvbnRlbnQtdHlwZTthdXRob3JpemF0aW9uO3gtZGV2aWNlLWlkO2FjY2VwdC1sYW5ndWFnZTtib2R5IiwiZWR0cyI6IjgwNmQ2N2JhYzdmY2ZjNDQ5ZmJkZTllNDExOGFkODY5NWJlZjFmMzQ3ZTIzN2E1YjgyZGQ0MThlM2JhNjE2ODUifQ.WsKUWYoyrEhd78kcyfoBk2cuqHFF_9F0oLpsnEoV5lD7yTw8Cu4Z9TgHPrLgEeVOSXXKNu45CBbzi2v3YhQOS7vLXDEHWI6BpoGjNFymsaVqsCA4bUmDtZ9mq2ugyeeIfZ5E6L0ywBF3BYAy8DnxRk8yyHSQCkuQm4W8AZnwXWzefdz5dCSljzTQtLli0x_s1hqOlYtAXtPvHQbx4OYPYkARrYHjRatiqyXECYNcgQGxbMs_knF7vgSk7uf0uSoJvbdpjPBd4xpnLbAWMHeDlhtG834r2bCFFKZJARGCfXZW_0y8PyJGNhscKIpg7BIfiEAgqIlcFMX3N0qbYaYl9w

jwt

Thanks

john
  • 2,324
  • 3
  • 20
  • 37
  • Hi John, could you add the output to your question? – Kelvin Apr 29 '20 at 21:56
  • Hi Kelvin. I just added the output to question. Thanks – john Apr 30 '20 at 05:35
  • the `headers={...}` parameter is for **additional** header fields. `typ` and `alg` are always present. There's no option to remove them. See [sourcecode on github](https://github.com/jpadilla/pyjwt/blob/master/jwt/api_jws.py) – jps Apr 30 '20 at 07:33
  • @jps But I have to make my api compatible with some service. Is there any possible way to overwrite it? – john Apr 30 '20 at 07:35
  • No easy way I could think of. Why does this header cause compatibility problems? – jps Apr 30 '20 at 07:41
  • or perhaps I should use a different library. Thanks @jps :) – john Apr 30 '20 at 07:42

3 Answers3

1

Just set the PyJWS.header_type to False|None. Make sure to define the headers that you actually need.

jwt.api_jws.PyJWS.header_typ = False
jwt.encode(..., headers={"alg": "HS512"})
1

For PyJWT >= 2.20

https://github.com/jpadilla/pyjwt/releases/tag/2.2.0

Just use:

jwt.encode(payload, key, algorithm, headers={'typ': None})

How does it work?

header = {"typ": self.header_typ, "alg": algorithm}
if headers:
    self._validate_headers(headers)
    header.update(headers)
    if not header["typ"]:
        del header["typ"]
YouJiacheng
  • 449
  • 3
  • 11
0

extending PyJWS.encode could override default header

import json
try:
    # import required by mypy to perform type checking, not used for normal execution
    from typing import Callable, Dict, List, Optional, Union # NOQA
except ImportError:
    pass

from jwt.algorithms import (
    Algorithm, get_default_algorithms, has_crypto, requires_cryptography  # NOQA
)
from jwt.utils import base64url_decode, base64url_encode, force_bytes, merge_dict
class MyPyJWS(PyJWS):

    def encode(self,
               payload,  # type: Union[Dict, bytes]
               key,  # type: str
               algorithm='HS256',  # type: str
               headers=None,  # type: Optional[Dict]
               json_encoder=None  # type: Optional[Callable]
               ):
        segments = []

        if algorithm is None:
            algorithm = 'none'

        if algorithm not in self._valid_algs:
            pass

        # Header
        header = {'alg': algorithm}

        if headers:
            self._validate_headers(headers)
            header.update(headers)

        json_header = force_bytes(
            json.dumps(
                header,
                separators=(',', ':'),
                cls=json_encoder
            )
        )

        segments.append(base64url_encode(json_header))
        segments.append(base64url_encode(payload))

        # Segments
        signing_input = b'.'.join(segments)
        try:
            alg_obj = self._algorithms[algorithm]
            key = alg_obj.prepare_key(key)
            signature = alg_obj.sign(signing_input, key)

        except KeyError:
            if not has_crypto and algorithm in requires_cryptography:
                raise NotImplementedError(
                    "Algorithm '%s' could not be found. Do you have cryptography "
                    "installed?" % algorithm
                )
            else:
                raise NotImplementedError('Algorithm not supported')

        segments.append(base64url_encode(signature))

        return b'.'.join(segments)

import jwt
encoded_jwt = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256')
print(encoded_jwt)
json_payload = json.dumps(
            {'some': 'payload'},
            separators=(',', ':')
        ).encode('utf-8')
encoded_jwt = MyPyJWS().encode(json_payload , 'secret', algorithm='HS256')
print(encoded_jwt)
Charles Chou
  • 179
  • 1
  • 15