I want to be able to encode a JWT token in flutter (dart) and to be to decode it in nodejs in order to use it as a google function for firebase.

the problem is that the encoded string in flutter produces an invalid token when I try to decode it with nodejs.

in both cases I use HS256 encryption.

this is my flutter code:

import 'package:jaguar_jwt/jaguar_jwt.dart';

final String emailTrackingJwtSecret = '<SECRET>';

String generateEmailTrackingJwtToken(String uid, String scanId, String composeId) {
  final claimSet = new JwtClaim(
      payload: {<PAYLOAD_DATA>}
  );
  final String token = issueJwtHS256(claimSet, emailTrackingJwtSecret);
  print(token);
  return token;
} 

and this is my nodejs code to decode it:

const jwt = require('jsonwebtoken');
const secret='<SECRET>';

const decoded = jwt.verify(code2,secret);

when I try to encode the same data with same secret in flutter I get the following token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDU5MjMwNTgsImlhdCI6MTU0NTgzNjY1OCwicGxkIjp7ImNvbXBvc2VJZCI6ImEyIiwic2NhbklkIjoiYTEiLCJ1aWQiOiJrZmlyIn19.INf2n8J3yA4KPlYToARNCJnDvDQWcobWs-abaPCn_FE=

in nodejs when I encode the same data I get:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJrZmlyIiwic2NhbklkIjoiYTEiLCJjb21wb3NlSWQiOiJhMiIsImlhdCI6MTU0NTgzNzEwM30.DWfGOppzqnmGmfP3OFY81S_0l2qR1ATH0nqMG7vcWMw

so the tokens are different.. and I read on https://github.com/auth0/node-jsonwebtoken and the default encryption is HS256 so what am I missing?

thank you


Solution 1: frsechet

When you encode JWTs, in most libraries, a "iat" (issued_at, basically the timestamp at which the token was created) field will be automatically added. Which means that the same payload with the same secret and algorithm, no matter the library, will not be the same if you encode it twice. This may explain why you get different encoded values.

This is how it is supposed to work by design. The only way to check if the jwt is valid is not by comparing it with the jwt you issued, but by decoding it with your secret (that only you, the server, knows).

Also, besides the fact that the dart jwt does not validate, the payload of your dart jwt is not the same as the payload from the node jwt. You may also want to check out why this is the case, because it also explains why the token is different!

As far as I can see your decode function is right. You should try this to see what is specifically wrong with your token:

try {
  const decoded = jwt.verify(code2,secret);
}
catch(err) {
  console.log(err);
}

Additionally, the token from dart looks base64 encoded, so the following code may solve your issue: jwt.verify(Buffer.from(code2, 'base64'), secret).