5AuthFilter::AuthFilter() {
7 auto app_config = nlohmann::to_nlohmann(drogon::app().getCustomConfig());
9 if (app_config.contains(SETTINGS_KEYNAME)) {
11 auto config = app_config.at(
"auth").get<AuthConfig>();
13 assert(config.type ==
"JWT");
14 assert(config.algorithm ==
"RS256");
17 nlohmann_verifier{jwt::default_clock()}
18 .with_audience(config.audience)
19 .with_issuer(config.issuer)
20 .allow_algorithm(jwt::algorithm::rs256(config.public_key));
21 LOG_INFO << config.type <<
" auth guard enabled (iss=" << config.issuer
22 <<
", aud=" << config.audience <<
")";
27 LOG_WARN <<
"No auth guard used...";
32void AuthFilter::doFilter(
const HttpRequestPtr &req,
34 FilterChainCallback &&fccb) {
37 if (!verifier.has_value()) {
38 auto user_id = req->getOptionalParameter<std::string>(USER_ID_NAME);
39 if (!user_id.has_value()) {
40 throw std::runtime_error(
"no user_id query parameter");
42 req->addCookie(USER_ID_NAME, user_id.value());
44 register_user(user_id.value());
49 extract_token_from_header(req->getHeader(AUTHORIZATION_HEADER));
51 auto decoded = jwt::decode<jwt::traits::nlohmann_json>(token);
52 verifier->verify(decoded);
54 auto subject = decoded.get_subject();
55 req->addCookie(USER_ID_NAME, subject);
57 register_user(subject);
59 }
catch (
const std::exception &err) {
60 LOG_WARN <<
"Auth check failed: " << err.what();
62 return fcb(cavoke::server::controllers::newStatusCodeResponse(
67std::string AuthFilter::extract_token_from_header(
68 const std::string &auth_header) {
69 if (auth_header.size() < TOKEN_PREFIX.size()) {
70 throw std::invalid_argument(
"Invalid Bearer token");
72 return {auth_header.begin() + TOKEN_PREFIX.size(), auth_header.end()};
75void AuthFilter::register_user(
const std::string &user_id)
const {
76 drogon_model::cavoke_orm::Users user;
78 drogon::app().getDbClient()->execSqlSync(
79 "insert into users (id) values ($1) on conflict do nothing", user_id);
83 return req->getCookie(USER_ID_NAME);
86const std::string AuthFilter::AUTHORIZATION_HEADER =
"Authorization";
87const std::string AuthFilter::TOKEN_PREFIX =
"Bearer ";
88const std::string AuthFilter::SETTINGS_KEYNAME =
"auth";
89const std::string AuthFilter::USER_ID_NAME =
"user_id";
static std::string get_user_id(const HttpRequestPtr &)
Acquires user_id parsed during AuthFilter's execution.