add auth verify api.
All checks were successful
Deploy / Build (push) Successful in 5m44s

This commit is contained in:
amass 2025-01-03 22:17:45 +08:00
parent c3f535e82e
commit 25bc92a45d
3 changed files with 35 additions and 44 deletions

View File

@ -122,6 +122,7 @@ void Application::authEvent() {
m_loginPage = m_navigationBar->removeLoginItem(); m_loginPage = m_navigationBar->removeLoginItem();
LOG(info) << "User logged out."; LOG(info) << "User logged out.";
} }
doJavaScript("if (window.updateAuthStatus) window.updateAuthStatus();");
} }
void Application::handlePathChange(const std::string &path) { void Application::handlePathChange(const std::string &path) {
@ -170,7 +171,7 @@ Server::Server(uint16_t port, const std::string &applicationRoot, const std::str
std::bind(&Server::createApplication, this, std::placeholders::_1, false)); std::bind(&Server::createApplication, this, std::placeholders::_1, false));
m_server->addEntryPoint(Wt::EntryPointType::WidgetSet, m_server->addEntryPoint(Wt::EntryPointType::WidgetSet,
std::bind(&Server::createApplication, this, std::placeholders::_1, true), "/wt/app.js"); std::bind(&Server::createApplication, this, std::placeholders::_1, true), "/wt/app.js");
m_server->addResource(std::make_shared<AuthenticationResource>(), "/auth/verify"); m_server->addResource(std::make_shared<AuthenticationResource>(), "/api/v1/auth/${tag}");
m_server->addResource(std::make_shared<PlaintextResource>(), "/plaintext"); m_server->addResource(std::make_shared<PlaintextResource>(), "/plaintext");
m_server->start(); m_server->start();

View File

@ -1,6 +1,7 @@
#include "Restful.h" #include "Restful.h"
#include "Application.h" #include "Application.h"
#include "Database/Session.h" #include "Database/Session.h"
#include "model/AuthModel.h"
#include <Wt/Auth/AuthService.h> #include <Wt/Auth/AuthService.h>
#include <Wt/Auth/Identity.h> #include <Wt/Auth/Identity.h>
#include <Wt/Dbo/Impl.h> #include <Wt/Dbo/Impl.h>
@ -8,39 +9,44 @@
#include <Wt/Dbo/backend/Sqlite3.h> #include <Wt/Dbo/backend/Sqlite3.h>
#include <Wt/Http/Response.h> #include <Wt/Http/Response.h>
#include <boost/scope/scope_exit.hpp> #include <boost/scope/scope_exit.hpp>
#include <format>
DBO_INSTANTIATE_TEMPLATES(MyMessage) DBO_INSTANTIATE_TEMPLATES(MyMessage)
DbStruct *m_dbStruct;
void AuthenticationResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) { void AuthenticationResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) {
auto tag = request.urlParam("tag");
LOG(info) << "path: " << request.path() << ", tag: " << tag;
response.setMimeType("application/json");
MyMessage message;
auto app = Amass::Singleton<WebToolkit::Server>::instance(); auto app = Amass::Singleton<WebToolkit::Server>::instance();
auto session = Database::session();
auto &service = app->authService(); auto &service = app->authService();
if (tag == "verify") {
auto enabled = service.authTokenUpdateEnabled(); auto session = Database::session();
boost::scope::scope_exit raii([&enabled, &service] { service.setAuthTokenUpdateEnabled(enabled); }); auto enabled = service.authTokenUpdateEnabled();
service.setAuthTokenUpdateEnabled(false); boost::scope::scope_exit raii([&enabled, &service] { service.setAuthTokenUpdateEnabled(enabled); });
Wt::Auth::AuthTokenState state; service.setAuthTokenUpdateEnabled(false);
Wt::Auth::User user; Wt::Auth::AuthTokenState state;
if (service.authTokensEnabled()) { Wt::Auth::User user;
const std::string *token = request.getCookieValue(service.authTokenCookieName()); if (service.authTokensEnabled()) {
if (token != nullptr) { const std::string *token = request.getCookieValue(service.authTokenCookieName());
Wt::Auth::AuthTokenResult result = service.processAuthToken(*token, session->users()); if (token != nullptr) {
state = result.state(); Wt::Auth::AuthTokenResult result = service.processAuthToken(*token, session->users());
if (state == Wt::Auth::AuthTokenState::Valid) { state = result.state();
user = result.user(); if (state == Wt::Auth::AuthTokenState::Valid) {
user = result.user();
}
} }
} }
if (user.isValid()) {
message.user = user.identity(Wt::Auth::Identity::LoginName).toUTF8();
}
LOG(info) << "state: " << (int)state << " " << message.user;
message.message = "Hello, World!";
message.status = state == Wt::Auth::AuthTokenState::Valid ? 0 : 404;
} else { // logout
response.addHeader("Set-Cookie", std::format("{}=; path={}; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT",
service.authTokenCookieName(), AuthModel::CookiePath));
} }
MyMessage message;
if (user.isValid()) {
message.user = user.identity(Wt::Auth::Identity::LoginName).toUTF8();
}
LOG(info) << "state: " << (int)state << " " << message.user;
response.setMimeType("application/json");
response.addHeader("Server", "Wt");
message.message = "Hello, World!";
Wt::Dbo::JsonSerializer writer(response.out()); Wt::Dbo::JsonSerializer writer(response.out());
writer.serialize(message); writer.serialize(message);
} }
@ -51,15 +57,5 @@ void PlaintextResource::handleRequest(const Wt::Http::Request &request, Wt::Http
response.out() << "Hello, World!"; response.out() << "Hello, World!";
} }
int DbStruct::rand() {
return distribution(rng);
}
AuthenticationResource::AuthenticationResource() { AuthenticationResource::AuthenticationResource() {
} }
DbStruct::DbStruct(const std::string &db) : rng(clock()), distribution(1, 10000) {
session.setConnection(std::make_unique<Wt::Dbo::backend::Sqlite3>(db));
session.mapClass<World>("world");
session.mapClass<Fortune>("fortune");
}

View File

@ -8,11 +8,13 @@
class MyMessage { class MyMessage {
public: public:
int status = 0;
std::string message; std::string message;
std::string user; std::string user;
template <class Action> template <class Action>
void persist(Action &a) { void persist(Action &a) {
Wt::Dbo::field(a, status, "status");
Wt::Dbo::field(a, message, "message"); Wt::Dbo::field(a, message, "message");
Wt::Dbo::field(a, user, "user"); Wt::Dbo::field(a, user, "user");
} }
@ -38,14 +40,6 @@ public:
} }
}; };
struct DbStruct {
DbStruct(const std::string &db);
int rand();
Wt::Dbo::Session session;
std::default_random_engine rng;
std::uniform_int_distribution<int> distribution;
};
class AuthenticationResource : public Wt::WResource { class AuthenticationResource : public Wt::WResource {
public: public:
AuthenticationResource(); AuthenticationResource();