Search code examples
pythondjangonginxdjango-rest-frameworkdjango-rest-framework-simplejwt

Append JWT as the "x-my-jwt" header to the upstream post request


Go a specific solution looking like this

High-level view

In Django as as you can see from my previous effort, got a specific endpoint

#urls.py
path('api/token/', MyTokenObtainPairView.as_view(), name='token_obtain'),

#views.py
class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

When I POST with an existing user like

Response given

I get a response where it's possible to see an access token similar to this

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNTkwOTE0MTk4LCJqdGkiOiJhZDZmNzZhZjFmOGU0ZWJlOGI2Y2Y5YjQ4MGQzZjY2MiIsInVzZXJfaWQiOjExLCJpYXQiOjE1OTA5MTc0OTgsInVzZXIiOiJ0aWFnbyIsImRhdGUiOiIyMDIwLTA1LTMxIn0.-5U9P-WWmhlOenzCvc6b7_71Tz17LyNxe_DOMwwqH4RqrNsilVukEcZWFRGupLHRZjIvPya2QJGpiju9ujzQuw

How can I append the JWT as the "x-my-jwt" header to the upstream POST request?


Solution

  • +---------+      +----------+           +--------+       +----------+
    |         |      |          |           |        |       |          |
    | Browser |----->|  Nginx   |---------->|Gunicorn| ----->|Django App|
    |         |      |          |           |        |       |          |
    +---------+      +----------+           +--------+       +----------+
    

    Browser requests for the Access token at /api/token Response:

    {
         "access" : "TOKENXYZ",
         "user" : "user",
         "date" : "2020-06-08",
    }
    

    Django Rest framework authenticator requires Authorization header to be present and that should have a prefix like Bearer, so you should set Authorization and x-my-jwt headers in the API call.

    From browse, if you're using jQuery then do something like this.

    $.ajax({
        type: 'POST',
        url: url,
        headers: {
            "x-my-jwt":"TOKEN_XYZ",
            "Authorization" : "Bearer TOKEN_XYZ"
        }
    }).done(function(data) { 
        alert(data);
    });
    

    If you are making API call from your Django App to other Django App server that requires JWT tokens then set headers using requests library as

    headers = {
       "x-my-jwt":"TOKEN_XYZ",
       "Authorization":"Bearer TOKEN_XYZ"
    }
    r = requests.post(url, data=payload, headers=headers)
    

    You can also do header rewrite at the Nginx level if you want. in that case, you need to set the Authorization header. Authorization header is the same as the access token you have received in api/token call with a prefix Bearer. If you do not want Bearer in the my-jwt token then remove the Bearer component,

    proxy_set_header X-my-jwt $http_authorization;