title: Jsonwebtoken verification causing NGINX timeout
body: <p>The general tech stack for the application I'm working on is NodeJS backend, React frontend, NGINX for a reverse proxy to link the two. All containerized using docker compose.</p>
  
  <p>The issue I seem to be running into is that when I try and verify JWTwhich are stored in an HTTP-only cookie, passed to the backend on API requests, it's being held up on verification causing a timeout. Specifically this error:</p>
  
  <p><code>6#6: *4 upstream prematurely closed connection while reading response header from upstream, client: 172.27.0.1, server: , request: "POST /api/api/v1/getUserInfo HTTP/1.1", upstream: "http://172.27.0.2:8080/api/v1/getUserInfo", host: "localhost", referrer: "http://localhost/account"</code></p>
  
  <p>I've tried upping the proxy_read_timeout/proxy_send_timeout in nginx but that doesn't seem to have helped.</p>
  
  <p>Here's my JWT signing function:</p>
  
  <pre class="lang-js prettyprint-override"><code>var privateKEY = 'testkey';
  const issuer: String = 'test123';
  const audience: String = 'test123';
  
  module.exports = {
      sign: (payload: any) =&gt; {
          // Token signing options
          var signOptions = {
              issuer:     issuer,
              audience: audience,
              expiresIn:  "12h", // 12 hour validity
          };
          return jwt.sign(payload, privateKEY, signOptions);
      }
  }
  </code></pre>
  
  <p>How I'm calling that function:</p>
  
  <pre class="lang-js prettyprint-override"><code>const token = jwt.sign({
                              id: user._id,
                              firstName: user.firstName,
                              role: user.role
                          });
  </code></pre>
  
  <p>How I'm getting the token from the cookie:</p>
  
  <pre class="lang-js prettyprint-override"><code>var cookieExtractor = function(req: Request) {
      var token = null;
      if (req &amp;&amp; req.cookies) {
          token = req.cookies["token"];
      }
  
      return token;
  };
  
  const issuer: string = "test123";
  const audience: string = "test123";
  
  var opts = {
      secretOrKey: 'testkey',
      issuer: issuer,
      audience: audience,
      jwtFromRequest: cookieExtractor
  };
  </code></pre>
  
  <p>My Passport-JWT strategy:</p>
  
  <pre class="lang-js prettyprint-override"><code>    passport.use(
          "jwt",
          new JWTStrategy(opts, (jwt_payload, done) =&gt; {
              UserModel.findOne({ _id: jwt_payload.id }, (err, user) =&gt; {
                  if (err) {
                      return done(err, false);
                  }
  
                  if (user) {
                      return done(null, user);
                  } else {
                      return done(null, false);
                  }
              });
          })
      );
  </code></pre>
  
  <p>How I'm calling the authentication:</p>
  
  <pre class="lang-js prettyprint-override"><code>    app.post(`${versioning}/updateUserInfo`, (req: Request, res: Response) =&gt; {
          passport.authenticate("jwt", { session: false }, (err, user, info) =&gt; {
              *insert code here*
          });
      });
  </code></pre>
  
  <p>When I've traced through the code, it seems to pause at a jwt.verify call in the passport-jwt library and then never gets past that. I'm new to JWT and all that so maybe I'm doing something wrong along the way, I just can't figure out why this all of a sudden stopped working (this is a side project and the last time I worked on it ~1 week ago, this problem never occurred).</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>For those experiencing this as well, I never found a clear reason as to why. I updated my jsonwebtoken library and stopped using Passport for my JWT verification and it started working for me. This is now my JWT verification method which I use instead of using the Passport method.</p>
  
  <pre><code>verifyTokenOnly: (token: any, cb: any) =&gt; {
      jwt.verify(
          token,
          publicUserKey,
          { audience: audience, algorithms: ["RS256"] },
          (err: any, jwt_payload: any) =&gt; {
              if (err || !jwt_payload) {
                  cb(err, null);
              } else {
                  UserModel.findOne({ _id: jwt_payload.sub }, (err, user) =&gt; {
                      if (err) {
                          cb(err, null);
                      }
  
                      if (user) {
                          cb(null, user);
                      } else {
                          cb(null, false);
                      }
                  });
              }
          }
      );
  },
  </code></pre>
  
  <p>Aside from doing that I didn't really change anything and it started working and hasn't happened since. </p>