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 <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include "jwt/string_view.hpp"
|
||||||
|
|
||||||
namespace jwt {
|
namespace jwt {
|
||||||
|
|
||||||
/*
|
/*!
|
||||||
* Encoding map.
|
* Encoding map.
|
||||||
*/
|
*/
|
||||||
class EMap
|
class EMap
|
||||||
|
@ -30,7 +31,8 @@ private:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
std::string base64_encode(const char* in, size_t len)
|
std::string base64_encode(const char* in, size_t len)
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
@ -120,7 +122,8 @@ private:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
std::string base64_decode(const char* in, size_t len)
|
std::string base64_decode(const char* in, size_t len)
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
@ -184,6 +187,31 @@ std::string base64_decode(const char* in, size_t len)
|
||||||
return result;
|
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
|
} // END namespace jwt
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,75 @@ std::ostream& operator<< (std::ostream& os, const T& obj)
|
||||||
return os;
|
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
|
} // END namespace jwt
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
#include "jwt/base64.hpp"
|
#include "jwt/base64.hpp"
|
||||||
|
#include "jwt/algorithm.hpp"
|
||||||
#include "jwt/string_view.hpp"
|
#include "jwt/string_view.hpp"
|
||||||
#include "jwt/detail/meta.hpp"
|
#include "jwt/detail/meta.hpp"
|
||||||
#include "jwt/json/json.hpp"
|
#include "jwt/json/json.hpp"
|
||||||
|
@ -342,6 +343,37 @@ private:
|
||||||
*/
|
*/
|
||||||
struct jwt_signature
|
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