0

On the client side, I request a proxy/gateway app, that should validate the JWT token, make a request to the backend and respond with data. If the token is invalid proxy app should respond with 401 'Unauthorized'.

function verifyToken(token: string) {
const authApiPublicKey = 
path.join(__dirname,'../../assets/keys/auth_api_public_key.cer');

return Promise.resolve(token)
.then((t) => jwt.decode(t, { complete: true }))
.then(() => fs.readFileSync(authApiPublicKey))
.then((key) => {
  try {
    return jwt.verify(token, key, {
      algorithms: ['RS256'],
    });
  } catch (err) {
    throw new Error('Error verifying the token');
  }
})
.then((payload) => {
  if (!payload) {
    throw new Error('Payload was malformed');
  }

  return payload;
});
}



 export default (request: Request, response: Response) => {
 const token: string = getToken(request);

 verifyToken(token)
  .then((payload) => {
  if (!payload) {
    response.status(401).send('Not authenticated');
  }
  return makeAuthRequest(
    request,
    response,
    () => ({
      endpointKey: 'affiliate. suppliers',
      method: 'GET',
      headers: {
        Accept: 'application/vnd.api+json',
        'Content-Type': 'application/vnd.api+json',
      },
      gzip: true,
    }),
    transformResponse,
  ).then(() => {
    response.end();
  });
})
.catch(() => {
  response.status(401).send('Not authenticated');
});
};

Originally the export default function looked like this:

export default (request: Request, response: Response) =>
 makeAuthRequest(
 request,
 response,
 () => ({
  endpointKey: 'affiliate.suppliers',
  method: 'GET',
  headers: {
    Accept: 'application/vnd.api+json',
    'Content-Type': 'application/vnd.api+json',
  },
  gzip: true,
 }),
 transformResponse,
 ).then(() => {
 response.end();
});

However, it always responded with data even if the token was invalid like this:

'this.invalid.token'

When I test my code in Postman I get a 'Not authenticated' response even with a valid token. I tried multiple approaches but non of them worked. One of them looked used to look like this:

function isTokenValid(token) {
 const authApiPublicKeyPath = path.join(__dirname, 'path_to_public_key_file.cer');
 const publicKey = fs.readFileSync(authApiPublicKeyPath);

 return new Promise((resolve) => {
  jwt.verify(token, publicKey, { algorithms: ['RS256'] }, (err) => {
   if (err) {
    resolve(false); // Token is invalid
   } else {
    resolve(true); // Token is valid
   }
  });
 });
 }

For jwt I need to use the 'jsonwebtoken' library, which is imported like so:

import path from 'path';
import jwt from 'JSON web token';
import fs from 'fs';

import makeAuthRequest from '../makeAuthRequest';
import getToken from '../getToken';
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • Have you tried supplying the private key to the verify function instead of the public key? –  Jul 26 '23 at 16:03
  • No, using the private key for verification will lead to incorrect results and can compromise the security of the token. – programmer24 Jul 26 '23 at 19:47
  • I just saw where you said this is client side. You really can't verify if a token is valid or not from the client side. See https://stackoverflow.com/questions/43788131/jwt-verify-client-side "You must verify the signature of JWS in the server always." –  Jul 26 '23 at 19:49
  • Are you just trying to extract the claims from the token? I am unsure why exactly you need to "validate" a JWT client side. –  Jul 26 '23 at 19:54
  • I am extracting it to get the payload. And with the kid property of the payload I can fetch the key, which I use in jwt.verify() – programmer24 Jul 26 '23 at 23:20

0 Answers0