Thalhammer / jwt-cpp

A header only library for creating and validating json web tokens in c++
https://thalhammer.github.io/jwt-cpp/
MIT License
864 stars 235 forks source link

[question] Can I add claims without id? #214

Closed MountainNine closed 2 years ago

MountainNine commented 2 years ago

For example, I want to add payload claims with this JSON format. {'test':'hello', 'test2':123} I looked jwt.h, and I found 'set_payload_claim' function. But this function needs 'id' parameter, and I don't want to contain id. Can I add this payload_claim without adding id? Thank you.

prince-chrismc commented 2 years ago

Hmm 🤔 I am not sure I understood your question so let me know if I missed the mark.

So JWT are JSON object those are key value pairs. If youd like to add a claim it needs to have a key (the API id might be unclear, let us know).

So if you use

https://github.com/Thalhammer/jwt-cpp/blob/9d1a010fea3ed3293112edec9745dc435a85a849/include/jwt-cpp/jwt.h#L2702

Like so

https://github.com/Thalhammer/jwt-cpp/blob/9d1a010fea3ed3293112edec9745dc435a85a849/example/private-claims.cpp#L30

You are able to add any JSON value for the id you want to access it with.

And for completeness, here's how youd access the value

https://github.com/Thalhammer/jwt-cpp/blob/9d1a010fea3ed3293112edec9745dc435a85a849/example/traits/kazuho-picojson.cpp#L36-L37

By passing the id... here's he output

https://github.com/Thalhammer/jwt-cpp/runs/5156063883?check_suite_focus=true#step:11:1605

MountainNine commented 2 years ago

What I want to do is to set payload claim without id.

According to the link,

https://github.com/Thalhammer/jwt-cpp/blob/9d1a010fea3ed3293112edec9745dc435a85a849/example/private-claims.cpp#L30

payload_claims variable is set to this.

{'object':{'test':'hello', 'test2':123}}

But I want to set payload_claims like this.

{'test':'hello', 'test2':123}

More specifically, I looked jwt.h, and found this code.

https://github.com/Thalhammer/jwt-cpp/blob/9d1a010fea3ed3293112edec9745dc435a85a849/include/jwt-cpp/jwt.h#L2702-L2705

What I want to do is to set payload_claims itself, not payload_claims[id], like this.

payload_claims = std::move(c)

How to implement this?

I apologize about Insufficient explanation.

MountainNine commented 2 years ago

Never Mind, I solved it by adding the function in jwt.h

        builder& set_payload(typename json_traits::object_type jsonStr) {
            payload_claims = std::move(jsonStr);
            return *this;
        }

Thanks for help, prince.

prince-chrismc commented 2 years ago

Ohh!

You could have called the method twice.

builder.set_payload_claim("test", /* json string hello */);
builder.set_payload_claim("test2", /* other */);

Thanks for sharing your solution!

PS you might be missing some other claims that are recommended like issuer. Not sure your application or situation but wanted to throw that in.

Thalhammer commented 2 years ago

@MountainNine If I understood correctly what you wanted to do is replace the payload claims entirely. You are right that this is not supported by default and the reason for this is simple: JWT requires certain claims to be present and set to correct values. Otherwise its not a valid jwt and jwt-cpp (or any other jwt library) will not correctly verify it. If you have a third party application that requires exactly this, then your way is probably fine, however if you control the layout of the jwt I highly recommend sticking with the defaults.

atlantis013 commented 1 year ago

Never Mind, I solved it by adding the function in jwt.h

      builder& set_payload(typename json_traits::object_type jsonStr) {
          payload_claims = std::move(jsonStr);
          return *this;
        }

Thanks for help, prince.

̶C̶a̶n̶ ̶y̶o̶u̶ ̶s̶h̶o̶w̶ ̶h̶o̶w̶ ̶s̶e̶t̶_̶p̶a̶y̶l̶o̶a̶d̶ ̶i̶s̶ ̶c̶a̶l̶l̶e̶d̶?̶ ̶M̶y̶ ̶p̶r̶o̶b̶l̶e̶m̶ ̶i̶s̶ ̶t̶o̶ ̶p̶a̶s̶s̶ ̶t̶o̶ ̶t̶h̶e̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶ ̶t̶h̶e̶ ̶j̶s̶o̶n̶ ̶t̶h̶a̶t̶ ̶I̶ ̶r̶e̶c̶e̶i̶v̶e̶d̶ ̶a̶s̶ ̶s̶t̶d̶:̶:̶s̶t̶r̶i̶n̶g̶.̶ ̶T̶h̶a̶n̶k̶ ̶y̶o̶u̶.̶

Solved.

std::string payload = "{'test':'hello', 'test2':123}";
picojson::value json_value;
std::string err = picojson::parse(json_value, payload);
if (!err.empty()) {
    std::cout << err << std::endl;
    return false;
}
auto token = jwt::create()
    .set_type("JWT")
    .set_payload(jwt::traits::kazuho_picojson::as_object(json_value))
    .sign(jwt::algorithm::rs256("", private_key, "", ""));