Search code examples
pythondjangodjango-rest-framework-simplejwt

Add extra data in JWT header, simple jwt


I want to override or extend Django simple JWT obtain token method to add 'kid' key to the token header, JWT format is header.payload.signiture, I know how to add it to payload but I need to add it to the header, is there any way?


Solution

  • there is no clean way, cause simple-jwt does not support any JWT header manipulation in its core.
    token objects provided by simple-jwt are a subclass of tokens.Token class and every time you get the encoded JWT token from the object you are calling tokens.Token.__str__ method that uses token_backend to call the function to encode the object to JWT, it is a headache to override __str__ method cause you must override almost all the codebase.
    the final solution is to write a custom encode method and pass the Token object and encode using token_backend and add extra headers.

    def custom_encode_token(token: Token):
            """
                NOTICE THIS IS THE DIRECT METHOD FROM SIMPLE_JWT.BACKENDS.TOKENBACKEND.encode MEHTOD
                ** may clash with next features developed for simple jwt itself
                current release used is ==> 4.6
    
            Returns an encoded token for the given payload dictionary.
            """
            jwt_payload = token.payload.copy()
            if api_settings.AUDIENCE is not None:
                jwt_payload['aud'] = api_settings.AUDIENCE
            if api_settings.ISSUER is not None:
                jwt_payload['iss'] = api_settings.ISSUER
            token = jwt.encode(
                jwt_payload, 
                api_settings.SIGNING_KEY, 
                algorithm=api_settings.ALGORITHM, 
                headers={'kid': '1'} # HERE WE ADD HEADER TO JWT
            )
            if isinstance(token, bytes):
                # For PyJWT <= 1.7.1
                return token.decode('utf-8')
            # For PyJWT >= 2.0.0a1
            return token