增加了用户认证接口
This commit is contained in:
parent
15374cc01e
commit
cfcdaac3e5
@ -42,6 +42,10 @@ if(NOT APPLE)
|
||||
# 在 CentOS 上使用 Boost 1.69
|
||||
set(BOOST_ROOT "/usr/include/boost169")
|
||||
set(BOOST_LIBRARYDIR "/usr/lib64/boost169")
|
||||
else()
|
||||
# 在 macOS 上使用 Homebrew 安装的 Boost
|
||||
set(BOOST_ROOT "/opt/homebrew/Cellar/boost/1.87.0")
|
||||
set(BOOST_LIBRARYDIR "/opt/homebrew/Cellar/boost/1.87.0/lib")
|
||||
endif()
|
||||
find_package(Boost 1.69.0 REQUIRED COMPONENTS system filesystem thread)
|
||||
|
||||
|
||||
@ -18,12 +18,17 @@
|
||||
{"point": "T8", "longitude": 120.08676664, "latitude": 36.35004529},
|
||||
{"point": "T9", "longitude": 120.08520616, "latitude": 36.34964473},
|
||||
{"point": "T10", "longitude": 120.08710569, "latitude": 36.34917893},
|
||||
{"point": "T11", "longitude": 120.0873865, "latitude": 36.3509885}
|
||||
{"point": "T11", "longitude": 120.0873865, "latitude": 36.3509885},
|
||||
{"point": "T12", "longitude": 120.08603613, "latitude": 36.35190217},
|
||||
{"point": "T13", "longitude": 120.08509148, "latitude": 36.35041247}
|
||||
]
|
||||
},
|
||||
"data_source": {
|
||||
"host": "localhost",
|
||||
"port": 8081,
|
||||
"username": "dianxin",
|
||||
"password": "dianxin@123",
|
||||
"auth_path": "/api/login",
|
||||
"aircraft_path": "/api/getCurrentFlightPositions",
|
||||
"vehicle_path": "/api/getCurrentVehiclePositions",
|
||||
"traffic_light_path": "/api/getTrafficLightSignals",
|
||||
|
||||
@ -1,14 +1,27 @@
|
||||
# 位置数据接口对接方案
|
||||
# 数据接口对接方案
|
||||
|
||||
## 第1章 位置数据接口对接方案
|
||||
|
||||
### 1.1 航空器位置数据接入
|
||||
### 1.1 登录认证
|
||||
|
||||
1. 登录接口:<http://IP:端口/login>
|
||||
2. 请求方式:post
|
||||
3. 参数:username、password
|
||||
4. 示例:<http://127.0.0.1:8080/login?username=XXXX&password=XXXX>
|
||||
5、返回值 data 为返回的鉴权token,后续接口需要再header中携带,data所有的数据是一个token,不要截断
|
||||
示例:{
|
||||
"status": 200,
|
||||
"msg": "登入成功",
|
||||
"data": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MzI3ODMwOTAsInVzZXJuYW1lIjoiYWRtaW4ifQ.y9feEL_9NT8UzED9NNkb0Ln6C-PBoufiSHWobWe5vWY"
|
||||
}
|
||||
|
||||
### 1.2 航空器位置数据接入
|
||||
|
||||
数据来源:接入并转发从空管接收到的融合数据
|
||||
|
||||
1. 接口地址:<http://IP:端口/openApi/getCurrentFlightPositions>
|
||||
|
||||
2. 请求方式:get
|
||||
2. 请求方式:get,需要在 Header 中携带认证信息,字段名为 Authorization,值为认证接口返回的token
|
||||
|
||||
3. 返回格式:以 JSON 格式返回数据,一次请求返回List集合对象
|
||||
|
||||
@ -23,13 +36,13 @@
|
||||
| 5 | altitude | 海拔高度 | double | 否 |
|
||||
| 6 | trackNumber | 航迹号 | String | 否 |
|
||||
|
||||
### 1.2 车辆位置数据接入
|
||||
### 1.3 车辆位置数据接入
|
||||
|
||||
数据来源:仅传递目前机场已接入的车辆位置数据
|
||||
|
||||
1. 接口地址:<http://IP:端口/openApi/getCurrentVehiclePositions>
|
||||
|
||||
2. 请求方式:get
|
||||
2. 请求方式:get,需要在 Header 中携带认证信息,字段名为 Authorization,值为认证接口返回的token
|
||||
|
||||
3. 返回格式:以 JSON 格式返回数据,一次请求返回List集合对象
|
||||
|
||||
@ -9,6 +9,9 @@ struct DataSourceConfig {
|
||||
std::string aircraft_path;
|
||||
std::string vehicle_path;
|
||||
std::string traffic_light_path;
|
||||
std::string auth_path; // 认证接口路径
|
||||
std::string username; // 用户名
|
||||
std::string password; // 密码
|
||||
int refresh_interval_ms;
|
||||
int timeout_ms; // 连接超时时间, 单位: 毫秒
|
||||
int read_timeout_ms; // 读取超时时间, 单位: 毫秒, 小于连接超时时间
|
||||
|
||||
@ -51,6 +51,9 @@ public:
|
||||
std::string aircraft_path;
|
||||
std::string vehicle_path;
|
||||
std::string traffic_light_path;
|
||||
std::string auth_path; // 认证接口路径
|
||||
std::string username; // 用户名
|
||||
std::string password; // 密码
|
||||
int refresh_interval_ms;
|
||||
int timeout_ms;
|
||||
int read_timeout_ms;
|
||||
@ -210,6 +213,9 @@ inline void to_json(json& j, const SystemConfig::DataSource& p) {
|
||||
{"aircraft_path", p.aircraft_path},
|
||||
{"vehicle_path", p.vehicle_path},
|
||||
{"traffic_light_path", p.traffic_light_path},
|
||||
{"auth_path", p.auth_path},
|
||||
{"username", p.username},
|
||||
{"password", p.password},
|
||||
{"refresh_interval_ms", p.refresh_interval_ms},
|
||||
{"timeout_ms", p.timeout_ms},
|
||||
{"read_timeout_ms", p.read_timeout_ms}
|
||||
@ -222,6 +228,9 @@ inline void from_json(const json& j, SystemConfig::DataSource& p) {
|
||||
j.at("aircraft_path").get_to(p.aircraft_path);
|
||||
j.at("vehicle_path").get_to(p.vehicle_path);
|
||||
j.at("traffic_light_path").get_to(p.traffic_light_path);
|
||||
j.at("auth_path").get_to(p.auth_path);
|
||||
j.at("username").get_to(p.username);
|
||||
j.at("password").get_to(p.password);
|
||||
j.at("refresh_interval_ms").get_to(p.refresh_interval_ms);
|
||||
j.at("timeout_ms").get_to(p.timeout_ms);
|
||||
j.at("read_timeout_ms").get_to(p.read_timeout_ms);
|
||||
|
||||
@ -69,8 +69,12 @@ bool System::initialize() {
|
||||
system_config.data_source.aircraft_path,
|
||||
system_config.data_source.vehicle_path,
|
||||
system_config.data_source.traffic_light_path,
|
||||
system_config.data_source.auth_path,
|
||||
system_config.data_source.username,
|
||||
system_config.data_source.password,
|
||||
system_config.data_source.refresh_interval_ms,
|
||||
system_config.data_source.timeout_ms
|
||||
system_config.data_source.timeout_ms,
|
||||
system_config.data_source.read_timeout_ms
|
||||
};
|
||||
|
||||
WarnConfig warnConfig{
|
||||
|
||||
@ -14,7 +14,8 @@ HTTPDataSource::HTTPDataSource(const DataSourceConfig& config)
|
||||
: config_(config)
|
||||
, host_(config.host)
|
||||
, port_(std::to_string(config.port))
|
||||
, last_health_check_(std::chrono::steady_clock::now()) {
|
||||
, last_health_check_(std::chrono::steady_clock::now())
|
||||
, is_authenticated_(false) {
|
||||
curl_ = curl_easy_init();
|
||||
if (!curl_) {
|
||||
Logger::error("Failed to initialize CURL");
|
||||
@ -36,7 +37,9 @@ bool HTTPDataSource::connect() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
// 进行认证
|
||||
return authenticate();
|
||||
}
|
||||
|
||||
void HTTPDataSource::disconnect() {
|
||||
@ -115,12 +118,20 @@ bool HTTPDataSource::ensureConnected() {
|
||||
return tryReconnect();
|
||||
}
|
||||
|
||||
bool HTTPDataSource::sendRequest(const std::string& path, std::string& response) {
|
||||
bool HTTPDataSource::sendRequest(const std::string& path, std::string& response, HttpMethod method) {
|
||||
if (!curl_) {
|
||||
Logger::error("CURL not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查认证状态
|
||||
if (!is_authenticated_) {
|
||||
Logger::error("Not authenticated");
|
||||
if (!authenticate()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string url = "http://" + host_ + ":" + port_ + path;
|
||||
Logger::debug("Sending request to: ", url);
|
||||
|
||||
@ -132,10 +143,24 @@ bool HTTPDataSource::sendRequest(const std::string& path, std::string& response)
|
||||
curl_easy_setopt(curl_, CURLOPT_CONNECTTIMEOUT, config_.timeout_ms / 1000);
|
||||
curl_easy_setopt(curl_, CURLOPT_NOSIGNAL, 1L);
|
||||
|
||||
// 根据方法设置不同的选项
|
||||
if (method == HttpMethod::GET) {
|
||||
curl_easy_setopt(curl_, CURLOPT_HTTPGET, 1L);
|
||||
} else if (method == HttpMethod::POST) {
|
||||
curl_easy_setopt(curl_, CURLOPT_POST, 1L);
|
||||
}
|
||||
|
||||
// 添加 HTTP 头
|
||||
struct curl_slist* headers = nullptr;
|
||||
headers = curl_slist_append(headers, "Accept: application/json");
|
||||
headers = curl_slist_append(headers, "Cache-Control: no-cache");
|
||||
|
||||
// 添加认证 token
|
||||
if (!auth_token_.empty()) {
|
||||
std::string auth_header = "Authorization: " + auth_token_;
|
||||
headers = curl_slist_append(headers, auth_header.c_str());
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
CURLcode res = curl_easy_perform(curl_);
|
||||
@ -148,6 +173,17 @@ bool HTTPDataSource::sendRequest(const std::string& path, std::string& response)
|
||||
|
||||
long http_code = 0;
|
||||
curl_easy_getinfo(curl_, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
|
||||
// 如果返回 401,尝试重新认证
|
||||
if (http_code == 401) {
|
||||
Logger::warning("Token expired, trying to re-authenticate");
|
||||
if (authenticate()) {
|
||||
// 重新发送请求
|
||||
return sendRequest(path, response, method);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (http_code != 200) {
|
||||
Logger::error("HTTP request failed with code: ", http_code);
|
||||
return false;
|
||||
@ -164,7 +200,7 @@ bool HTTPDataSource::fetchAircraftData(std::vector<Aircraft>& aircraft) {
|
||||
}
|
||||
|
||||
std::string response;
|
||||
if (!sendRequest(config_.aircraft_path, response)) {
|
||||
if (!sendRequest(config_.aircraft_path, response, HttpMethod::GET)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -179,7 +215,7 @@ bool HTTPDataSource::fetchVehicleData(std::vector<Vehicle>& vehicles) {
|
||||
}
|
||||
|
||||
std::string response;
|
||||
if (!sendRequest(config_.vehicle_path, response)) {
|
||||
if (!sendRequest(config_.vehicle_path, response, HttpMethod::GET)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -194,7 +230,7 @@ bool HTTPDataSource::fetchTrafficLightSignals(std::vector<TrafficLightSignal>& s
|
||||
}
|
||||
|
||||
std::string response;
|
||||
if (!sendRequest(config_.traffic_light_path, response)) {
|
||||
if (!sendRequest(config_.traffic_light_path, response, HttpMethod::GET)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -363,4 +399,86 @@ bool HTTPDataSource::parseAircraftResponse(const std::string& response, std::vec
|
||||
Logger::error("Error processing aircraft response: ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool HTTPDataSource::authenticate() {
|
||||
std::lock_guard<std::mutex> lock(auth_mutex_);
|
||||
|
||||
if (!curl_) {
|
||||
Logger::error("CURL not initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 构造认证请求URL
|
||||
std::string url = "http://" + host_ + ":" + port_ + config_.auth_path;
|
||||
|
||||
// 构造认证请求体
|
||||
nlohmann::json request = {
|
||||
{"username", config_.username},
|
||||
{"password", config_.password}
|
||||
};
|
||||
|
||||
std::string request_body = request.dump();
|
||||
std::string response;
|
||||
|
||||
Logger::debug("Sending authentication request with username: ", config_.username);
|
||||
Logger::debug("Request body: ", request_body);
|
||||
|
||||
// 设置CURL选项
|
||||
curl_easy_reset(curl_);
|
||||
curl_easy_setopt(curl_, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curl_, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, request_body.c_str());
|
||||
curl_easy_setopt(curl_, CURLOPT_POSTFIELDSIZE, static_cast<long>(request_body.length()));
|
||||
curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &response);
|
||||
|
||||
// 设置请求头
|
||||
struct curl_slist* headers = nullptr;
|
||||
headers = curl_slist_append(headers, "Content-Type: application/json");
|
||||
curl_easy_setopt(curl_, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
// 发送请求
|
||||
CURLcode res = curl_easy_perform(curl_);
|
||||
curl_slist_free_all(headers);
|
||||
|
||||
if (res != CURLE_OK) {
|
||||
Logger::error("Failed to authenticate: ", curl_easy_strerror(res));
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查响应状态码
|
||||
long http_code = 0;
|
||||
curl_easy_getinfo(curl_, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
|
||||
if (http_code != 200) {
|
||||
Logger::error("Authentication failed with HTTP code: ", http_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Logger::debug("Authentication response: ", response);
|
||||
|
||||
// 解析响应获取 token
|
||||
nlohmann::json j = nlohmann::json::parse(response);
|
||||
if (!j.contains("status") || !j.contains("msg") || !j.contains("data")) {
|
||||
Logger::error("Authentication response missing required fields");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (j["status"].get<int>() != 200) {
|
||||
Logger::error("Authentication failed: ", j["msg"].get<std::string>());
|
||||
return false;
|
||||
}
|
||||
|
||||
auth_token_ = j["data"].get<std::string>();
|
||||
is_authenticated_ = true;
|
||||
Logger::debug("Stored token: ", auth_token_);
|
||||
Logger::info("Successfully authenticated: ", j["msg"].get<std::string>());
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
Logger::error("Failed to parse authentication response: ", e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,11 @@
|
||||
|
||||
class HTTPDataSource : public DataSource {
|
||||
public:
|
||||
enum class HttpMethod {
|
||||
GET,
|
||||
POST
|
||||
};
|
||||
|
||||
explicit HTTPDataSource(const DataSourceConfig& config);
|
||||
~HTTPDataSource() override;
|
||||
|
||||
@ -40,11 +45,18 @@ private:
|
||||
static constexpr int HEALTH_CHECK_INTERVAL = 60; // 健康检查间隔(秒)
|
||||
std::atomic<bool> is_reconnecting_{false}; // 重连状态标志
|
||||
|
||||
std::string auth_token_; // 认证 token
|
||||
bool is_authenticated_; // 认证状态
|
||||
std::mutex auth_mutex_; // 认证相关的互斥锁
|
||||
|
||||
bool authenticate(); // 认证方法
|
||||
bool refreshToken(); // 刷新 token
|
||||
|
||||
bool tryReconnect();
|
||||
bool ensureConnected();
|
||||
bool checkConnectionHealth(); // 检查连接健康状况
|
||||
|
||||
bool sendRequest(const std::string& path, std::string& response);
|
||||
bool sendRequest(const std::string& path, std::string& response, HttpMethod method = HttpMethod::GET);
|
||||
bool parseAircraftResponse(const std::string& response, std::vector<Aircraft>& aircraft);
|
||||
bool parseVehicleResponse(const std::string& response, std::vector<Vehicle>& vehicles);
|
||||
bool parseTrafficLightResponse(const std::string& response, std::vector<TrafficLightSignal>& signals);
|
||||
|
||||
@ -401,7 +401,7 @@ TEST_F(BasicCollisionTest, QN002AircraftCrossing) {
|
||||
|
||||
// 记录详细的测试信息
|
||||
Logger::debug("QN002-AC001 碰撞测试结果:");
|
||||
Logger::debug("碰<EFBFBD><EFBFBD>类型: ", static_cast<int>(result.type));
|
||||
Logger::debug("碰撞类型: ", static_cast<int>(result.type));
|
||||
Logger::debug("最小距离: ", result.minDistance, "m");
|
||||
Logger::debug("碰撞时间: ", result.timeToCollision, "s");
|
||||
Logger::debug("碰撞点: (", result.collisionPoint.x, ",", result.collisionPoint.y, ")");
|
||||
@ -460,7 +460,7 @@ TEST_F(BasicCollisionTest, CrossingBeforeAndAfter) {
|
||||
Logger::debug("无人车位置: (", vehicle.position.x, ",", vehicle.position.y, ")");
|
||||
Logger::debug("交叉点位置: (", crossPoint.x, ",", crossPoint.y, ")");
|
||||
|
||||
ASSERT_FALSE(risks.empty()) << "交叉前应该检测到<EFBFBD><EFBFBD>撞风险";
|
||||
ASSERT_FALSE(risks.empty()) << "交叉前应该检测到碰撞风险";
|
||||
EXPECT_EQ(risks[0].level, RiskLevel::WARNING) << "交叉前应该是预警级别";
|
||||
|
||||
// 2. 测试交叉过程中
|
||||
@ -477,7 +477,7 @@ TEST_F(BasicCollisionTest, CrossingBeforeAndAfter) {
|
||||
risks = detector_->detectCollisions();
|
||||
|
||||
// 记录详细的测试信息
|
||||
Logger::debug("交叉过程<EFBFBD><EFBFBD>碰撞检测:");
|
||||
Logger::debug("交叉过程碰撞检测:");
|
||||
Logger::debug("航空器位置: (", aircraft.position.x, ",", aircraft.position.y, ")");
|
||||
Logger::debug("无人车位置: (", vehicle.position.x, ",", vehicle.position.y, ")");
|
||||
|
||||
|
||||
@ -67,6 +67,9 @@ POINT_T11 = {"longitude": 120.0873865, "latitude": 36.3509885}
|
||||
# QN002 新起点(距离 T6 路口 150 米)
|
||||
POINT_T12 = {"longitude": 120.08603613, "latitude": 36.35190217} # T4 和 T6 之间,距 T6 150米
|
||||
|
||||
# AC001 新起点(距离 T6 路口 200 米)
|
||||
POINT_T13 = {"longitude": 120.08509148, "latitude": 36.35041247} # T6向南 200 米
|
||||
|
||||
# 飞机和车辆尺寸(半径 米)
|
||||
AIRCRAFT_SIZE_M = 30.0
|
||||
VEHICLE_SIZE_M = 10.0
|
||||
@ -551,7 +554,7 @@ def update_aircraft_position(aircraft, elapsed_time):
|
||||
reached_target = update_position_with_vector(
|
||||
aircraft,
|
||||
POINT_T11, # 目标点
|
||||
POINT_T7, # 起点
|
||||
POINT_T13, # 起点
|
||||
aircraft["speed"],
|
||||
elapsed_time,
|
||||
return_to_start=True # 航空器需要返回起点
|
||||
@ -735,8 +738,22 @@ last_aircraft_update_time = time.time()
|
||||
last_vehicle_update_time = time.time()
|
||||
last_light_switch_time = time.time()
|
||||
|
||||
@app.route('/api/getCurrentFlightPositions')
|
||||
def check_auth():
|
||||
auth_header = request.headers.get('Authorization')
|
||||
if not auth_header or auth_header != AUTH_TOKEN:
|
||||
return False
|
||||
return True
|
||||
|
||||
@app.route('/api/getCurrentFlightPositions', methods=['GET', 'OPTIONS'])
|
||||
def get_flight_positions():
|
||||
if request.method == 'OPTIONS':
|
||||
return '', 204
|
||||
if not check_auth():
|
||||
return jsonify({
|
||||
"status": 401,
|
||||
"msg": "认证失败",
|
||||
"data": None
|
||||
}), 401
|
||||
global last_aircraft_update_time
|
||||
current_time = time.time()
|
||||
elapsed_time = current_time - last_aircraft_update_time
|
||||
@ -773,8 +790,16 @@ def switch_traffic_light_state():
|
||||
if old_state != traffic_light_data[1]["state"]:
|
||||
print(f"东路口红绿灯状态切换为: {'绿灯' if traffic_light_data[1]['state'] == 1 else '红灯'}")
|
||||
|
||||
@app.route('/api/getCurrentVehiclePositions')
|
||||
@app.route('/api/getCurrentVehiclePositions', methods=['GET', 'OPTIONS'])
|
||||
def get_vehicle_positions():
|
||||
if request.method == 'OPTIONS':
|
||||
return '', 204
|
||||
if not check_auth():
|
||||
return jsonify({
|
||||
"status": 401,
|
||||
"msg": "认证失败",
|
||||
"data": None
|
||||
}), 401
|
||||
global last_vehicle_update_time
|
||||
current_time = time.time()
|
||||
elapsed_time = current_time - last_vehicle_update_time
|
||||
@ -796,8 +821,16 @@ def get_vehicle_positions():
|
||||
print(f"Error in get_vehicle_positions: {str(e)}")
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
@app.route('/api/getTrafficLightSignals')
|
||||
@app.route('/api/getTrafficLightSignals', methods=['GET', 'OPTIONS'])
|
||||
def get_traffic_light_signals():
|
||||
if request.method == 'OPTIONS':
|
||||
return '', 204
|
||||
if not check_auth():
|
||||
return jsonify({
|
||||
"status": 401,
|
||||
"msg": "认证失败",
|
||||
"data": None
|
||||
}), 401
|
||||
current_time = time.time()
|
||||
|
||||
# 更新时间戳
|
||||
@ -812,8 +845,9 @@ def get_traffic_light_signals():
|
||||
@app.after_request
|
||||
def add_cors_headers(response):
|
||||
response.headers['Access-Control-Allow-Origin'] = '*'
|
||||
response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
|
||||
response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
|
||||
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
|
||||
response.headers['Access-Control-Max-Age'] = '3600'
|
||||
return response
|
||||
|
||||
def check_vehicle_states():
|
||||
@ -821,5 +855,38 @@ def check_vehicle_states():
|
||||
for vehicle_no, state in vehicle_states.items():
|
||||
state.log_state()
|
||||
|
||||
# 认证相关配置
|
||||
AUTH_USERNAME = "dianxin"
|
||||
AUTH_PASSWORD = "dianxin@123"
|
||||
AUTH_TOKEN = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MzI3ODMwOTAsInVzZXJuYW1lIjoiYWRtaW4ifQ.y9feEL_9NT8UzED9NNkb0Ln6C-PBoufiSHWobWe5vWY"
|
||||
|
||||
@app.route('/api/login', methods=['POST', 'OPTIONS'])
|
||||
def login():
|
||||
if request.method == 'OPTIONS':
|
||||
return '', 204
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({
|
||||
"status": 400,
|
||||
"msg": "请求格式错误",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
username = data.get('username')
|
||||
password = data.get('password')
|
||||
|
||||
if username == AUTH_USERNAME and password == AUTH_PASSWORD:
|
||||
return jsonify({
|
||||
"status": 200,
|
||||
"msg": "登入成功",
|
||||
"data": AUTH_TOKEN
|
||||
})
|
||||
else:
|
||||
return jsonify({
|
||||
"status": 401,
|
||||
"msg": "用户名或密码错误",
|
||||
"data": None
|
||||
}), 401
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='localhost', port=8081, debug=True)
|
||||
Loading…
Reference in New Issue
Block a user