81 lines
2.2 KiB
C++
81 lines
2.2 KiB
C++
#include "jwt.h"
|
|
#include <random>
|
|
|
|
#include "utils.h"
|
|
|
|
std::string http::auth::jwt::secretKey;
|
|
|
|
void http::auth::jwt::generateSecretKey() {
|
|
secretKey.clear();
|
|
|
|
std::random_device rd;
|
|
std::mt19937 generator(rd());
|
|
std::uniform_int_distribution<> distribution('!', '~');
|
|
for (size_t i = 0; i < 32; ++i) {
|
|
secretKey += static_cast<char>(distribution(generator));
|
|
}
|
|
}
|
|
|
|
// payload, signature
|
|
static std::pair<std::string, std::string> parseJwtFromCookie(const std::string& input) {
|
|
std::string val1, val2;
|
|
size_t dotPos = input.find('.');
|
|
|
|
// Если точка найдена
|
|
if (dotPos != std::string::npos) {
|
|
val1 = input.substr(0, dotPos);
|
|
|
|
// Если в val1 есть еще точки, нужно найти последнюю точку
|
|
size_t lastDotPos = val1.find_last_of('.');
|
|
if (lastDotPos != std::string::npos) {
|
|
val1 = val1.substr(0, lastDotPos + 1);
|
|
}
|
|
|
|
val2 = input.substr(dotPos + 1);
|
|
} else {
|
|
// Точка не найдена, val1 - вся строка
|
|
val1 = input;
|
|
}
|
|
|
|
return std::make_pair(http::utils::b64Decode(val1), val2);
|
|
}
|
|
|
|
http::auth::jwt::Jwt http::auth::jwt::Jwt::fromCookies(const std::string &cookie) {
|
|
auto pc = utils::parseCookies(cookie);
|
|
Jwt t;
|
|
if (pc.find("auth") != pc.end()) {
|
|
auto tmp = parseJwtFromCookie(pc.at("auth"));
|
|
t.payload = tmp.first;
|
|
t.signature = tmp.second;
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
http::auth::jwt::Jwt http::auth::jwt::Jwt::fromUser(const std::string &user) {
|
|
Jwt t;
|
|
t.payload = user;
|
|
return t;
|
|
}
|
|
|
|
bool http::auth::jwt::Jwt::isValid() {
|
|
if (payload.empty() || signature.empty()) {
|
|
return false;
|
|
}
|
|
|
|
auto realSignature = utils::sha256(this->payload + secretKey);
|
|
return signature == realSignature;
|
|
}
|
|
|
|
std::string http::auth::jwt::Jwt::getUsername() {
|
|
return payload;
|
|
}
|
|
|
|
std::string http::auth::jwt::Jwt::asCookie() {
|
|
signature = utils::sha256(this->payload + secretKey);
|
|
auto val = utils::b64Encode(payload) + "." + signature;
|
|
return "auth=" + val + ";Path=/; Max-Age=86400; HttpOnly; SameSite=Lax";
|
|
}
|
|
|
|
http::auth::jwt::Jwt::~Jwt() = default;
|