Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audience, issuer, expiration, etc are lost when using a string as payload. #6

Closed
dbrabera opened this issue Apr 12, 2014 · 6 comments
Closed

Comments

@dbrabera
Copy link
Contributor

When using a string as payload, the issuer, expiration, audience and subject are lost. It is not possible to attach properties to a primitive and also they do not get serialized anyway, as it get serialized as a string. A possible solution is to put the string in a object literal and attach this data to the literal too.

At the moment, using a string as payload also causes a parsing exception when decoding it due to a problem in the node-jws library.

@woloski
Copy link
Contributor

woloski commented Apr 12, 2014

can you show a code example or ideally a test?

@dbrabera
Copy link
Contributor Author

This tests will cause the node-jws library to raise a SintaxError. I did a pull request to that library today. A workaround is to serialize the payload with JSON.stringify before sending it to node-jws. This can be done for example in the sing function of node-jsonwebtoken. Then, the second test will fail because the properties attached to the string payload are lost and thus the payload doesn't has any expiration date.

  describe('when signing a token with a string as payload', function() {
    var secret = 'shhhhhh';
    var payload = 'relevant string goes here';

    it('should validate with secret', function(done) {
      var token = jwt.sign(payload, secret);
      jwt.verify(token, secret, function(err, decoded) {
        assert.ok(decoded);
        assert.equal(payload, decoded);
        done();
      });
    });

    it('should be invalid when is expired', function(done) {
      var token = jwt.sign(payload, secret, { expiresInMinutes: -10 });
      jwt.verify(token, secret, function(err, decoded) {
        assert.isUndefined(decoded);
        assert.isNotNull(err);
        done();
      });
    });
  });

By the way, very interesting the blog of your company : )

@cromestant
Copy link

I think this is in the same issue category,
when decoding JWT the payload is set as a string, and this the audience validation does not work ( or any by the way:

module.exports.verify = function(jwtString, secretOrPublicKey, options, callback) {
  if ((typeof options === 'function') && !callback) callback = options;
  if (!options) options = {};
console.log("options are")
  console.log(options)

  var valid;
  try {
    valid = jws.verify(jwtString, secretOrPublicKey);
  }
  catch (e) {
    return callback(e);
  }

  if (!valid)
    return callback(new Error('invalid signature'));

  var payload = this.decode(jwtString);
  var Type = require('type-of-is')
  console.log(Type(payload))

outputs the following:

[Function: String]
this should be an object at this point, in my case the fix will be to JSON.parse the payload before assigning it.

@cromestant
Copy link

SOrry invalidate my previous comment, header was commint without the "typ" field, which is causing the jws module to not json decode once again:

function jwsDecode(jwsSig, opts) {
  opts = opts || {};
     jwsSig = toString(jwsSig);
    if (!isValidJws(jwsSig))
    return null;
    const header = headerFromJWS(jwsSig);
    if (!header)
    return null;
    var payload = payloadFromJWS(jwsSig);
    if (header.typ === 'JWT' || opts.json)
        payload = JSON.parse(payload);
    return {
        header: header,
        payload: payload,
        signature: signatureFromJWS(jwsSig),
        }
        }

my current solution will be to use the "opt" to force the serialization.

@incredibleweirdo
Copy link

I have come across the same issue when using an integer as the payload. Not a big deal to workaround (now pass my integer as a value in JSON object), but it was mystifying at first why no tokens were expiring.

var jwt = require('jsonwebtoken');
var secret = '1234567890'

var token = jwt.sign(10909334, secret, {expiresInMinutes: 30});

jwt.verify(token, secret, function(err, decoded){
     if (err) { 
         console.log('Error: ' err);
     } else {
        console.log(decoded);
     };
});

results in '10909334' being printed to the console.

@woloski
Copy link
Contributor

woloski commented Aug 23, 2014

yes, payload needs to be an object today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants