From c3f535e82e651fdb98393b519c6bc00d8d25edc0 Mon Sep 17 00:00:00 2001 From: amass Date: Fri, 3 Jan 2025 14:12:02 +0800 Subject: [PATCH] update cookie lifetime. --- Server/Live2dBackend.cpp | 2 +- WebApplication/Application.cpp | 38 +++++++++++++++- WebApplication/Application.h | 6 +++ WebApplication/CMakeLists.txt | 3 +- WebApplication/LoginPage.cpp | 2 + WebApplication/VisitorRecordsPage.cpp | 2 +- WebApplication/model/AuthModel.cpp | 44 +++++++++++++++++++ WebApplication/model/AuthModel.h | 14 ++++++ .../{ => model}/VisitorRecordTableModel.cpp | 0 .../{ => model}/VisitorRecordTableModel.h | 0 10 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 WebApplication/model/AuthModel.cpp create mode 100644 WebApplication/model/AuthModel.h rename WebApplication/{ => model}/VisitorRecordTableModel.cpp (100%) rename WebApplication/{ => model}/VisitorRecordTableModel.h (100%) diff --git a/Server/Live2dBackend.cpp b/Server/Live2dBackend.cpp index 9ea243f..5fff156 100644 --- a/Server/Live2dBackend.cpp +++ b/Server/Live2dBackend.cpp @@ -14,7 +14,7 @@ Live2dBackend::Live2dBackend() { using namespace boost::beast; boost::urls::url_view view(request.target()); auto target = view.path(); - LOG(info) << target; + // LOG(info) << target; if (target.find("..") != boost::beast::string_view::npos) { session.reply(ServiceLogic::badRequest(request, "Illegal request-target")); return; diff --git a/WebApplication/Application.cpp b/WebApplication/Application.cpp index f61133c..67cbd0e 100644 --- a/WebApplication/Application.cpp +++ b/WebApplication/Application.cpp @@ -7,6 +7,7 @@ #include "NavigationBar.h" #include "Restful.h" #include "VisitorRecordsPage.h" +#include "model/AuthModel.h" #include #include #include @@ -113,6 +114,8 @@ void Application::authEvent() { auto token = env.getCookie(service.authTokenCookieName()); if (token == nullptr) { Wt::Http::Cookie cookie(service.authTokenCookieName(), service.createAuthToken(u)); + cookie.setPath(AuthModel::CookiePath); + cookie.setExpires(Wt::WDateTime()); setCookie(cookie); } } else { @@ -187,7 +190,7 @@ void Server::initializeAuthenticationService() { m_authService = std::make_unique(); m_authService->setEmailVerificationEnabled(true); m_authService->setEmailVerificationRequired(true); - m_authService->setAuthTokensEnabled(true, "logincookie"); + m_authService->setAuthTokensEnabled(true); m_passwordService = std::make_unique(*m_authService); auto verifier = std::make_unique(); @@ -204,4 +207,37 @@ Wt::Auth::AuthService &Server::authService() { const Wt::Auth::PasswordService &Server::passwordService() { return *m_passwordService; } + +void Server::insertCookie(const std::string &cookie) { + if (!m_cookies.contains(cookie)) { + m_cookies.insert(cookie); + } +} + +Wt::Http::Cookie Server::updateCookie(const std::string &oldCookie, const Wt::Auth::AuthTokenResult &result, bool secure) { + Wt::Http::Cookie cookie(m_authService->authTokenCookieName()); + cookie.setPath(AuthModel::CookiePath); + cookie.setSecure(secure); + if (result.state() == Wt::Auth::AuthTokenState::Invalid) { + if (m_cookies.contains(oldCookie)) { + m_cookies.erase(oldCookie); + } + cookie.setMaxAge(std::chrono::seconds(0)); + cookie.setValue(""); + } else { + auto newToken = result.newToken(); + if (!newToken.empty()) { + if (m_cookies.contains(oldCookie)) { // 勾选了记住我 + m_cookies.erase(oldCookie); + cookie.setMaxAge(std::chrono::seconds(result.newTokenValidity())); + m_cookies.insert(newToken); + } else { // 只在会话期间有效 + cookie.setExpires(Wt::WDateTime()); + } + cookie.setValue(newToken); + } + } + return cookie; +} + } // namespace WebToolkit \ No newline at end of file diff --git a/WebApplication/Application.h b/WebApplication/Application.h index 5dc837d..362ea47 100644 --- a/WebApplication/Application.h +++ b/WebApplication/Application.h @@ -4,6 +4,7 @@ #include "Singleton.h" #include #include +#include namespace Wt { class WServer; @@ -13,6 +14,7 @@ class WEnvironment; namespace Auth { class AuthService; class PasswordService; +class AuthTokenResult; } // namespace Auth }; // namespace Wt @@ -51,6 +53,8 @@ public: void initializeAuthenticationService(); Wt::Auth::AuthService &authService(); const Wt::Auth::PasswordService &passwordService(); + void insertCookie(const std::string &cookie); + Wt::Http::Cookie updateCookie(const std::string &oldCookie, const Wt::Auth::AuthTokenResult &result, bool secure); protected: Server(uint16_t port, const std::string &applicationRoot, const std::string &documentRoot); @@ -61,6 +65,8 @@ private: std::unique_ptr m_authService; std::unique_ptr m_passwordService; + + std::unordered_set m_cookies; }; } // namespace WebToolkit #endif // __WEBAPPLICATION_H__ \ No newline at end of file diff --git a/WebApplication/CMakeLists.txt b/WebApplication/CMakeLists.txt index bbb93e5..68b2041 100644 --- a/WebApplication/CMakeLists.txt +++ b/WebApplication/CMakeLists.txt @@ -7,9 +7,10 @@ add_library(WebApplication LoginPage.h LoginPage.cpp NavigationBar.h NavigationBar.cpp VisitorRecordsPage.h VisitorRecordsPage.cpp - VisitorRecordTableModel.h VisitorRecordTableModel.cpp Restful.h Restful.cpp Dialog.h Dialog.cpp + model/AuthModel.h model/AuthModel.cpp + model/VisitorRecordTableModel.h model/VisitorRecordTableModel.cpp ) get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) diff --git a/WebApplication/LoginPage.cpp b/WebApplication/LoginPage.cpp index 29adc04..1d29ba3 100644 --- a/WebApplication/LoginPage.cpp +++ b/WebApplication/LoginPage.cpp @@ -1,5 +1,6 @@ #include "LoginPage.h" #include "Application.h" +#include "model/AuthModel.h" #include #include #include @@ -7,6 +8,7 @@ LoginPage::LoginPage(const Wt::Auth::AuthService &baseAuth, Wt::Auth::AbstractUserDatabase &users, Wt::Auth::Login &login) : Wt::Auth::AuthWidget(baseAuth, users, login) { + setModel(std::make_unique(baseAuth, users)); auto app = Amass::Singleton::instance(); // setInternalBasePath("/wt"); model()->addPasswordAuth(&app->passwordService()); diff --git a/WebApplication/VisitorRecordsPage.cpp b/WebApplication/VisitorRecordsPage.cpp index a8fe62c..9810084 100644 --- a/WebApplication/VisitorRecordsPage.cpp +++ b/WebApplication/VisitorRecordsPage.cpp @@ -1,7 +1,7 @@ #include "VisitorRecordsPage.h" #include "BoostLog.h" #include "Database/Session.h" -#include "VisitorRecordTableModel.h" +#include "model/VisitorRecordTableModel.h" #include #include #include diff --git a/WebApplication/model/AuthModel.cpp b/WebApplication/model/AuthModel.cpp new file mode 100644 index 0000000..aa3a607 --- /dev/null +++ b/WebApplication/model/AuthModel.cpp @@ -0,0 +1,44 @@ +#include "AuthModel.h" +#include "../Application.h" +#include +#include +#include + +AuthModel::AuthModel(const Wt::Auth::AuthService &baseAuth, Wt::Auth::AbstractUserDatabase &users) + : Wt::Auth::AuthModel(baseAuth, users) { +} + +Wt::Auth::User AuthModel::processAuthToken() { + using namespace Wt::Auth; + if (baseAuth()->authTokensEnabled()) { + Wt::WApplication *app = Wt::WApplication::instance(); + const Wt::WEnvironment &env = app->environment(); + const std::string *token = env.getCookie(baseAuth()->authTokenCookieName()); + if (token) { + AuthTokenResult result = baseAuth()->processAuthToken(*token, users()); + auto server = Amass::Singleton::instance(); + auto cookie = server->updateCookie(*token, result, app->environment().urlScheme() == "https"); + if ((result.state() == AuthTokenState::Invalid) || !cookie.value().empty()) { + app->setCookie(cookie); + } + return result.state() == AuthTokenState::Valid ? result.user() : User(); + } + } + return User(); +} + +void AuthModel::setRememberMeCookie(const Wt::Auth::User &user) { + using namespace Wt::Auth; + Wt::WApplication *app = Wt::WApplication::instance(); + const AuthService *s = baseAuth(); + + Wt::Http::Cookie cookie(s->authTokenCookieName(), s->createAuthToken(user), + std::chrono::seconds(s->authTokenValidity() * 60)); + cookie.setDomain(s->authTokenCookieDomain()); + cookie.setPath(CookiePath); + cookie.setSecure(app->environment().urlScheme() == "https"); + + auto server = Amass::Singleton::instance(); + server->insertCookie(cookie.value()); + app->setCookie(cookie); +} diff --git a/WebApplication/model/AuthModel.h b/WebApplication/model/AuthModel.h new file mode 100644 index 0000000..08d80ca --- /dev/null +++ b/WebApplication/model/AuthModel.h @@ -0,0 +1,14 @@ +#ifndef __AUTHMODEL_H__ +#define __AUTHMODEL_H__ + +#include + +class AuthModel : public Wt::Auth::AuthModel { +public: + static constexpr auto CookiePath = "/"; + AuthModel(const Wt::Auth::AuthService &baseAuth, Wt::Auth::AbstractUserDatabase &users); + Wt::Auth::User processAuthToken() final; + void setRememberMeCookie(const Wt::Auth::User &user) final; +}; + +#endif // __AUTHMODEL_H__ \ No newline at end of file diff --git a/WebApplication/VisitorRecordTableModel.cpp b/WebApplication/model/VisitorRecordTableModel.cpp similarity index 100% rename from WebApplication/VisitorRecordTableModel.cpp rename to WebApplication/model/VisitorRecordTableModel.cpp diff --git a/WebApplication/VisitorRecordTableModel.h b/WebApplication/model/VisitorRecordTableModel.h similarity index 100% rename from WebApplication/VisitorRecordTableModel.h rename to WebApplication/model/VisitorRecordTableModel.h