mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-16 17:58:32 +00:00
JWT encoding
This commit is contained in:
parent
e7d52450d6
commit
8277e2cbd3
5 changed files with 156 additions and 3 deletions
|
@ -3,10 +3,11 @@
|
|||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include "jwt/string_view.hpp"
|
||||
|
||||
namespace jwt {
|
||||
|
||||
/*
|
||||
/*!
|
||||
* Encoding map.
|
||||
*/
|
||||
class EMap
|
||||
|
@ -30,7 +31,8 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
*/
|
||||
std::string base64_encode(const char* in, size_t len)
|
||||
{
|
||||
std::string result;
|
||||
|
@ -120,7 +122,8 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
*/
|
||||
std::string base64_decode(const char* in, size_t len)
|
||||
{
|
||||
std::string result;
|
||||
|
@ -184,6 +187,31 @@ std::string base64_decode(const char* in, size_t len)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
*/
|
||||
void base64_uri_encode(char* data, size_t len) noexcept
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
|
||||
for (; i < len; ++i) {
|
||||
switch (data[i]) {
|
||||
case '+':
|
||||
data[j++] = '-';
|
||||
break;
|
||||
case '/':
|
||||
data[j++] = '_';
|
||||
break;
|
||||
case '=':
|
||||
break;
|
||||
default:
|
||||
data[j++] = data[i];
|
||||
};
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // END namespace jwt
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,75 @@ std::ostream& operator<< (std::ostream& os, const T& obj)
|
|||
return os;
|
||||
}
|
||||
|
||||
std::string jwt_signature::encode(const jwt_header& header,
|
||||
const jwt_payload& payload)
|
||||
{
|
||||
std::string jwt_msg;
|
||||
//TODO: Optimize allocations
|
||||
|
||||
sign_func_t sign_fn = get_algorithm_impl(header);
|
||||
|
||||
std::string hdr_sign = header.base64_encode();
|
||||
std::string pld_sign = payload.base64_encode();
|
||||
|
||||
base64_uri_encode(&hdr_sign[0], hdr_sign.length());
|
||||
base64_uri_encode(&pld_sign[0], pld_sign.length());
|
||||
|
||||
std::string data = hdr_sign + '.' + pld_sign;
|
||||
auto res = sign_fn(key_, data);
|
||||
|
||||
std::string b64hash = base64_encode(res.first.c_str(), res.first.length());
|
||||
base64_uri_encode(&b64hash[0], b64hash.length());
|
||||
|
||||
jwt_msg = data + '.' + b64hash;
|
||||
|
||||
return jwt_msg;
|
||||
}
|
||||
|
||||
|
||||
sign_func_t
|
||||
jwt_signature::get_algorithm_impl(const jwt_header& hdr) const noexcept
|
||||
{
|
||||
sign_func_t ret = nullptr;
|
||||
|
||||
switch (hdr.algo()) {
|
||||
case algorithm::HS256:
|
||||
ret = HMACSign<algo::HS256>::sign;
|
||||
break;
|
||||
case algorithm::HS384:
|
||||
ret = HMACSign<algo::HS384>::sign;
|
||||
break;
|
||||
case algorithm::HS512:
|
||||
ret = HMACSign<algo::HS512>::sign;
|
||||
break;
|
||||
case algorithm::NONE:
|
||||
ret = HMACSign<algo::NONE>::sign;
|
||||
break;
|
||||
case algorithm::RS256:
|
||||
ret = PEMSign<algo::RS256>::sign;
|
||||
break;
|
||||
case algorithm::RS384:
|
||||
ret = PEMSign<algo::RS384>::sign;
|
||||
break;
|
||||
case algorithm::RS512:
|
||||
ret = PEMSign<algo::RS512>::sign;
|
||||
break;
|
||||
case algorithm::ES256:
|
||||
ret = PEMSign<algo::ES256>::sign;
|
||||
break;
|
||||
case algorithm::ES384:
|
||||
ret = PEMSign<algo::ES384>::sign;
|
||||
break;
|
||||
case algorithm::ES512:
|
||||
ret = PEMSign<algo::ES512>::sign;
|
||||
break;
|
||||
default:
|
||||
assert (0 && "Code not reached");
|
||||
};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // END namespace jwt
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <ostream>
|
||||
|
||||
#include "jwt/base64.hpp"
|
||||
#include "jwt/algorithm.hpp"
|
||||
#include "jwt/string_view.hpp"
|
||||
#include "jwt/detail/meta.hpp"
|
||||
#include "jwt/json/json.hpp"
|
||||
|
@ -342,6 +343,37 @@ private:
|
|||
*/
|
||||
struct jwt_signature
|
||||
{
|
||||
public: // 'tors
|
||||
/// Default constructor
|
||||
jwt_signature() = default;
|
||||
|
||||
/*!
|
||||
*/
|
||||
jwt_signature(string_view key)
|
||||
: key_(key.data(), key.length())
|
||||
{
|
||||
}
|
||||
|
||||
/// Default copy and assignment operator
|
||||
jwt_signature(const jwt_signature&) = default;
|
||||
jwt_signature& operator=(const jwt_signature&) = default;
|
||||
|
||||
~jwt_signature() = default;
|
||||
|
||||
public: // Exposed APIs
|
||||
/*!
|
||||
*/
|
||||
std::string encode(const jwt_header& header,
|
||||
const jwt_payload& payload);
|
||||
|
||||
private: // Private implementation
|
||||
/*!
|
||||
*/
|
||||
sign_func_t get_algorithm_impl(const jwt_header& hdr) const noexcept;
|
||||
|
||||
private: // Data members;
|
||||
/// The key for creating the JWS
|
||||
std::string key_;
|
||||
};
|
||||
|
||||
|
||||
|
|
BIN
include/jwt/test/test_jwt_signature
Executable file
BIN
include/jwt/test/test_jwt_signature
Executable file
Binary file not shown.
24
include/jwt/test/test_jwt_signature.cc
Normal file
24
include/jwt/test/test_jwt_signature.cc
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include <iostream>
|
||||
#include "jwt/jwt.hpp"
|
||||
|
||||
void basic_sign_test()
|
||||
{
|
||||
// Create header
|
||||
jwt::jwt_header hdr;
|
||||
hdr = jwt::jwt_header{jwt::algorithm::HS256};
|
||||
|
||||
// Create payload
|
||||
jwt::jwt_payload jp;
|
||||
jp.add_claim("sub", "1234567890");
|
||||
jp.add_claim("name", "John Doe");
|
||||
jp.add_claim("admin", true);
|
||||
|
||||
jwt::jwt_signature sgn{"secret"};
|
||||
auto res = sgn.sign(hdr, jp);
|
||||
std::cout << res << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
basic_sign_test();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue