59 lines
2.4 KiB
C++
59 lines
2.4 KiB
C++
#include "AuthService.hpp"
|
||
|
||
#include <QJsonObject>
|
||
#include <QJsonValue>
|
||
#include <string>
|
||
|
||
#include "ApiChain.hpp"
|
||
#include "ApiClient.hpp"
|
||
#include "AuthLoads.hpp"
|
||
#include "crypto/RsaEncryptor.hpp"
|
||
|
||
namespace geopro::net {
|
||
|
||
namespace {
|
||
|
||
constexpr int kCodeSuccess = 200;
|
||
|
||
const char* const kPathImageCode = "/business/system/personalUser/getImageCode";
|
||
const char* const kPathVerifyCode = "/business/system/personalUser/verifyCodeCheck";
|
||
const char* const kPathLogin = "/admin/tenant/auth/login2";
|
||
|
||
} // namespace
|
||
|
||
AuthService::AuthService(ApiClient& api, std::string rsaPublicKeyPem)
|
||
: api_(api), rsaPublicKeyPem_(std::move(rsaPublicKeyPem)) {}
|
||
|
||
CaptchaLoad* AuthService::fetchCaptchaAsync() {
|
||
IApiCall* call = api_.getAsync(QString::fromLatin1(kPathImageCode));
|
||
return new CaptchaLoad(call);
|
||
}
|
||
|
||
LoginLoad* AuthService::loginAsync(const QString& username, const QString& password,
|
||
const QString& code, const QString& codeId) {
|
||
// 失败判定与同步版一致:服务端 code != 200 或存在传输层 rawError。
|
||
auto isFailure = [](const ApiResponse& r) { return r.code != kCodeSuccess || !r.rawError.isEmpty(); };
|
||
|
||
// step1:校验验证码(与 captcha 同会话)。
|
||
ApiChain::StepFactory step1 = [this, code, codeId](const QList<ApiResponse>&) -> IApiCall* {
|
||
const QJsonObject body{{QStringLiteral("code"), code}, {QStringLiteral("codeId"), codeId}};
|
||
return api_.postJsonAsync(QString::fromLatin1(kPathVerifyCode), body);
|
||
};
|
||
|
||
// step2:RSA 加密密码(PKCS#1 v1.5 -> base64,可抛 std::exception → ApiChain 转 failed)-> login2。
|
||
ApiChain::StepFactory step2 = [this, username, password, code, codeId](const QList<ApiResponse>&) -> IApiCall* {
|
||
RsaEncryptor enc(rsaPublicKeyPem_);
|
||
const std::string encrypted = enc.encryptBase64(password.toStdString());
|
||
const QJsonObject body{{QStringLiteral("username"), username},
|
||
{QStringLiteral("password"), QString::fromStdString(encrypted)},
|
||
{QStringLiteral("checkCode"), code}, // 用户输入的验证码(后端 checkCodeNotNull)
|
||
{QStringLiteral("codeId"), codeId}};
|
||
return api_.postJsonAsync(QString::fromLatin1(kPathLogin), body);
|
||
};
|
||
|
||
auto* chain = new ApiChain({step1, step2}, isFailure);
|
||
return new LoginLoad(chain);
|
||
}
|
||
|
||
} // namespace geopro::net
|