feat: 更新Podfile和Podfile.lock,移除Alamofire依赖并添加API认证机制文档
- 注释掉Podfile中的Alamofire依赖,更新Podfile.lock以反映更改。 - 在yana/APIs/API-README.md中新增自动认证Header机制的详细文档,描述其工作原理、实现细节及最佳实践。 - 在yana/yanaApp.swift中将print语句替换为debugInfo以增强调试信息的输出。 - 在API相关文件中实现用户认证状态检查和相关header的自动添加逻辑,提升API请求的安全性和用户体验。 - 更新多个文件中的日志输出,确保在DEBUG模式下提供详细的调试信息。
This commit is contained in:
152
yana/APIs/API-README.md
Normal file
152
yana/APIs/API-README.md
Normal file
@@ -0,0 +1,152 @@
|
||||
## 🔐 **自动认证 Header 机制**
|
||||
|
||||
### 概述
|
||||
|
||||
系统会自动检查用户的登录状态,并在所有API请求中自动添加认证相关的header。
|
||||
|
||||
### 工作原理
|
||||
|
||||
1. **检查认证状态**:每次发起API请求时,系统会检查`AccountModel`的有效性
|
||||
2. **自动添加Header**:如果用户已登录且认证信息有效,自动添加以下header:
|
||||
- `pub_uid`: 用户唯一标识(来自`AccountModel.uid`)
|
||||
- `pub_ticket`: 业务会话票据(来自`AccountModel.ticket`)
|
||||
|
||||
### 实现细节
|
||||
|
||||
```swift
|
||||
// 在 APIConfiguration.defaultHeaders 中实现
|
||||
static var defaultHeaders: [String: String] {
|
||||
var headers = [
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
// ... 其他基础header
|
||||
]
|
||||
|
||||
// 检查用户认证状态并添加相关 headers
|
||||
let authStatus = UserInfoManager.checkAuthenticationStatus()
|
||||
|
||||
if authStatus.canAutoLogin {
|
||||
// 添加认证 headers(仅在 AccountModel 有效时)
|
||||
if let userId = UserInfoManager.getCurrentUserId() {
|
||||
headers["pub_uid"] = userId
|
||||
}
|
||||
|
||||
if let userTicket = UserInfoManager.getCurrentUserTicket() {
|
||||
headers["pub_ticket"] = userTicket
|
||||
}
|
||||
}
|
||||
|
||||
return headers
|
||||
}
|
||||
```
|
||||
|
||||
### 认证状态检查
|
||||
|
||||
系统使用`UserInfoManager.checkAuthenticationStatus()`检查认证状态:
|
||||
|
||||
```swift
|
||||
enum AuthenticationStatus {
|
||||
case valid // 认证有效,可以自动登录
|
||||
case invalid // 认证信息不完整或无效
|
||||
case notFound // 未找到认证信息
|
||||
}
|
||||
```
|
||||
|
||||
**认证有效的条件**:
|
||||
- `AccountModel`存在
|
||||
- `uid`不为空
|
||||
- `ticket`不为空
|
||||
- `accessToken`不为空
|
||||
|
||||
### 使用方式
|
||||
|
||||
认证header的添加是**完全自动的**,开发者无需手动处理:
|
||||
|
||||
```swift
|
||||
// 示例:发起API请求
|
||||
let request = ConfigRequest()
|
||||
let response = try await apiService.request(request)
|
||||
|
||||
// 如果用户已登录,以上请求会自动包含:
|
||||
// Header: pub_uid = "12345"
|
||||
// Header: pub_ticket = "eyJhbGciOiJIUzI1NiJ9..."
|
||||
```
|
||||
|
||||
### 测试功能
|
||||
|
||||
在DEBUG模式下,可以使用测试方法验证功能:
|
||||
|
||||
```swift
|
||||
#if DEBUG
|
||||
// 运行认证header测试
|
||||
UserInfoManager.testAuthenticationHeaders()
|
||||
#endif
|
||||
```
|
||||
|
||||
测试包括:
|
||||
1. **未登录状态测试**:验证不会添加认证header
|
||||
2. **已登录状态测试**:验证正确添加认证header
|
||||
3. **清理测试**:验证测试数据正确清理
|
||||
|
||||
### 调试日志
|
||||
|
||||
在DEBUG模式下,系统会输出认证header的添加情况:
|
||||
|
||||
```
|
||||
🔐 添加认证 header: pub_uid = 12345
|
||||
🔐 添加认证 header: pub_ticket = eyJhbGciOiJIUzI1NiJ9...
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```
|
||||
🔐 跳过认证 header 添加 - 认证状态: 未找到认证信息
|
||||
```
|
||||
|
||||
### 最佳实践
|
||||
|
||||
1. **登录成功后保存完整认证信息**:
|
||||
```swift
|
||||
UserInfoManager.saveCompleteAuthenticationData(
|
||||
accessToken: loginResponse.accessToken,
|
||||
ticket: ticketResponse.ticket,
|
||||
uid: loginResponse.uid,
|
||||
userInfo: loginResponse.userInfo
|
||||
)
|
||||
```
|
||||
|
||||
2. **登出时清理认证信息**:
|
||||
```swift
|
||||
UserInfoManager.clearAllAuthenticationData()
|
||||
```
|
||||
|
||||
3. **应用启动时检查认证状态**:
|
||||
```swift
|
||||
let authStatus = UserInfoManager.checkAuthenticationStatus()
|
||||
if authStatus.canAutoLogin {
|
||||
// 可以直接进入主界面
|
||||
} else {
|
||||
// 需要重新登录
|
||||
}
|
||||
```
|
||||
|
||||
### 安全考虑
|
||||
|
||||
- **内存安全**:ticket存储在内存中,应用重启需重新获取
|
||||
- **持久化安全**:uid和accessToken存储在Keychain中,确保安全性
|
||||
- **自动清理**:认证失效时系统会自动停止添加认证header
|
||||
|
||||
### 故障排除
|
||||
|
||||
1. **认证header未添加**:
|
||||
- 检查用户是否已正确登录
|
||||
- 验证AccountModel是否包含有效的uid和ticket
|
||||
- 确认认证状态为valid
|
||||
|
||||
2. **ticket为空**:
|
||||
- 检查登录流程是否正确获取了ticket
|
||||
- 验证ticket是否正确保存到AccountModel
|
||||
|
||||
3. **调试模式下查看详细日志**:
|
||||
- 启用DEBUG模式查看认证header添加日志
|
||||
- 使用测试方法验证功能正确性
|
||||
@@ -94,13 +94,28 @@ struct APIConfiguration {
|
||||
"User-Agent": "YuMi/20.20.61 (iPhone; iOS 16.4; Scale/2.00)"
|
||||
]
|
||||
|
||||
// 添加用户认证相关 headers(如果存在)
|
||||
if let userId = UserInfoManager.getCurrentUserId() {
|
||||
headers["pub_uid"] = userId
|
||||
}
|
||||
// 检查用户认证状态并添加相关 headers
|
||||
let authStatus = UserInfoManager.checkAuthenticationStatus()
|
||||
|
||||
if let userTicket = UserInfoManager.getCurrentUserTicket() {
|
||||
headers["pub_ticket"] = userTicket
|
||||
if authStatus.canAutoLogin {
|
||||
// 添加用户认证相关 headers(仅在 AccountModel 有效时)
|
||||
if let userId = UserInfoManager.getCurrentUserId() {
|
||||
headers["pub_uid"] = userId
|
||||
#if DEBUG
|
||||
debugInfo("🔐 添加认证 header: pub_uid = \(userId)")
|
||||
#endif
|
||||
}
|
||||
|
||||
if let userTicket = UserInfoManager.getCurrentUserTicket() {
|
||||
headers["pub_ticket"] = userTicket
|
||||
#if DEBUG
|
||||
debugInfo("🔐 添加认证 header: pub_ticket = \(userTicket.prefix(20))...")
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#if DEBUG
|
||||
debugInfo("🔐 跳过认证 header 添加 - 认证状态: \(authStatus.description)")
|
||||
#endif
|
||||
}
|
||||
|
||||
return headers
|
||||
|
||||
@@ -22,7 +22,11 @@ class APILogger {
|
||||
|
||||
// MARK: - Request Logging
|
||||
static func logRequest<T: APIRequestProtocol>(_ request: T, url: URL, body: Data?, finalHeaders: [String: String]? = nil) {
|
||||
#if DEBUG
|
||||
guard logLevel != .none else { return }
|
||||
#else
|
||||
return
|
||||
#endif
|
||||
|
||||
let timestamp = dateFormatter.string(from: Date())
|
||||
|
||||
@@ -107,7 +111,11 @@ class APILogger {
|
||||
|
||||
// MARK: - Response Logging
|
||||
static func logResponse(data: Data, response: HTTPURLResponse, duration: TimeInterval) {
|
||||
#if DEBUG
|
||||
guard logLevel != .none else { return }
|
||||
#else
|
||||
return
|
||||
#endif
|
||||
|
||||
let timestamp = dateFormatter.string(from: Date())
|
||||
let statusEmoji = response.statusCode < 400 ? "✅" : "❌"
|
||||
@@ -143,7 +151,11 @@ class APILogger {
|
||||
|
||||
// MARK: - Error Logging
|
||||
static func logError(_ error: Error, url: URL?, duration: TimeInterval) {
|
||||
#if DEBUG
|
||||
guard logLevel != .none else { return }
|
||||
#else
|
||||
return
|
||||
#endif
|
||||
|
||||
let timestamp = dateFormatter.string(from: Date())
|
||||
|
||||
@@ -186,7 +198,11 @@ class APILogger {
|
||||
|
||||
// MARK: - Decoded Response Logging
|
||||
static func logDecodedResponse<T>(_ response: T, type: T.Type) {
|
||||
#if DEBUG
|
||||
guard logLevel == .detailed else { return }
|
||||
#else
|
||||
return
|
||||
#endif
|
||||
|
||||
let timestamp = dateFormatter.string(from: Date())
|
||||
print("🎯 [Decoded Response] [\(timestamp)] Type: \(type)")
|
||||
@@ -203,7 +219,11 @@ class APILogger {
|
||||
|
||||
// MARK: - Performance Logging
|
||||
static func logPerformanceWarning(duration: TimeInterval, threshold: TimeInterval = 5.0) {
|
||||
#if DEBUG
|
||||
guard logLevel != .none && duration > threshold else { return }
|
||||
#else
|
||||
return
|
||||
#endif
|
||||
|
||||
let timestamp = dateFormatter.string(from: Date())
|
||||
print("\n⚠️ [Performance Warning] [\(timestamp)] ============")
|
||||
|
||||
@@ -260,21 +260,27 @@ struct UserInfoManager {
|
||||
return getAccountModel()?.accessToken
|
||||
}
|
||||
|
||||
// MARK: - Ticket Management (内存存储)
|
||||
// MARK: - Ticket Management (优先从 AccountModel 获取)
|
||||
private static var currentTicket: String?
|
||||
|
||||
static func getCurrentUserTicket() -> String? {
|
||||
// 优先从 AccountModel 获取 ticket(确保一致性)
|
||||
if let accountTicket = getAccountModel()?.ticket, !accountTicket.isEmpty {
|
||||
return accountTicket
|
||||
}
|
||||
|
||||
// 备选:从内存获取(用于兼容性)
|
||||
return currentTicket
|
||||
}
|
||||
|
||||
static func saveTicket(_ ticket: String) {
|
||||
currentTicket = ticket
|
||||
print("💾 保存 Ticket 到内存")
|
||||
debugInfo("💾 保存 Ticket 到内存")
|
||||
}
|
||||
|
||||
static func clearTicket() {
|
||||
currentTicket = nil
|
||||
print("🗑️ 清除 Ticket")
|
||||
debugInfo("🗑️ 清除 Ticket")
|
||||
}
|
||||
|
||||
// MARK: - User Info Management
|
||||
@@ -283,9 +289,9 @@ struct UserInfoManager {
|
||||
do {
|
||||
try keychain.store(userInfo, forKey: StorageKeys.userInfo)
|
||||
userInfoCache = userInfo
|
||||
print("💾 保存用户信息成功")
|
||||
debugInfo("💾 保存用户信息成功")
|
||||
} catch {
|
||||
print("❌ 保存用户信息失败: \(error)")
|
||||
debugError("❌ 保存用户信息失败: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -303,7 +309,7 @@ struct UserInfoManager {
|
||||
userInfoCache = userInfo
|
||||
return userInfo
|
||||
} catch {
|
||||
print("❌ 读取用户信息失败: \(error)")
|
||||
debugError("❌ 读取用户信息失败: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -337,7 +343,7 @@ struct UserInfoManager {
|
||||
saveUserInfo(userInfo)
|
||||
}
|
||||
|
||||
print("✅ 完整认证信息保存成功")
|
||||
debugInfo("✅ 完整认证信息保存成功")
|
||||
}
|
||||
|
||||
/// 检查是否有有效的认证信息
|
||||
@@ -351,7 +357,7 @@ struct UserInfoManager {
|
||||
clearUserInfo()
|
||||
clearTicket()
|
||||
|
||||
print("🗑️ 清除所有认证信息")
|
||||
debugInfo("🗑️ 清除所有认证信息")
|
||||
}
|
||||
|
||||
/// 尝试恢复 Ticket(用于应用重启后)
|
||||
@@ -361,7 +367,7 @@ struct UserInfoManager {
|
||||
return false
|
||||
}
|
||||
|
||||
print("🔄 尝试使用 Access Token 恢复 Ticket...")
|
||||
debugInfo("🔄 尝试使用 Access Token 恢复 Ticket...")
|
||||
|
||||
// 这里需要注入 APIService 依赖,暂时返回 false
|
||||
// 实际实现中应该调用 TicketHelper.createTicketRequest
|
||||
@@ -382,9 +388,9 @@ struct UserInfoManager {
|
||||
saveTicket(ticket)
|
||||
}
|
||||
|
||||
print("💾 AccountModel 保存成功")
|
||||
debugInfo("💾 AccountModel 保存成功")
|
||||
} catch {
|
||||
print("❌ AccountModel 保存失败: \(error)")
|
||||
debugError("❌ AccountModel 保存失败: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,7 +410,7 @@ struct UserInfoManager {
|
||||
accountModelCache = accountModel
|
||||
return accountModel
|
||||
} catch {
|
||||
print("❌ 读取 AccountModel 失败: \(error)")
|
||||
debugError("❌ 读取 AccountModel 失败: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -414,7 +420,7 @@ struct UserInfoManager {
|
||||
/// - Parameter ticket: 新的票据
|
||||
static func updateAccountModelTicket(_ ticket: String) {
|
||||
guard var accountModel = getAccountModel() else {
|
||||
print("❌ 无法更新 ticket:AccountModel 不存在")
|
||||
debugError("❌ 无法更新 ticket:AccountModel 不存在")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -449,9 +455,9 @@ struct UserInfoManager {
|
||||
do {
|
||||
try keychain.delete(forKey: StorageKeys.accountModel)
|
||||
accountModelCache = nil
|
||||
print("🗑️ AccountModel 已清除")
|
||||
debugInfo("🗑️ AccountModel 已清除")
|
||||
} catch {
|
||||
print("❌ 清除 AccountModel 失败: \(error)")
|
||||
debugError("❌ 清除 AccountModel 失败: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -462,9 +468,9 @@ struct UserInfoManager {
|
||||
do {
|
||||
try keychain.delete(forKey: StorageKeys.userInfo)
|
||||
userInfoCache = nil
|
||||
print("🗑️ UserInfo 已清除")
|
||||
debugInfo("🗑️ UserInfo 已清除")
|
||||
} catch {
|
||||
print("❌ 清除 UserInfo 失败: \(error)")
|
||||
debugError("❌ 清除 UserInfo 失败: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -474,7 +480,7 @@ struct UserInfoManager {
|
||||
cacheQueue.async(flags: .barrier) {
|
||||
accountModelCache = nil
|
||||
userInfoCache = nil
|
||||
print("🗑️ 清除所有内存缓存")
|
||||
debugInfo("🗑️ 清除所有内存缓存")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,7 +491,7 @@ struct UserInfoManager {
|
||||
_ = getAccountModel()
|
||||
// 预加载 UserInfo
|
||||
_ = getUserInfo()
|
||||
print("🚀 缓存预加载完成")
|
||||
debugInfo("🚀 缓存预加载完成")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,29 +502,29 @@ struct UserInfoManager {
|
||||
static func checkAuthenticationStatus() -> AuthenticationStatus {
|
||||
return cacheQueue.sync {
|
||||
guard let accountModel = getAccountModel() else {
|
||||
print("🔍 认证检查:未找到 AccountModel")
|
||||
debugInfo("🔍 认证检查:未找到 AccountModel")
|
||||
return .notFound
|
||||
}
|
||||
|
||||
// 检查 uid 是否有效
|
||||
guard let uid = accountModel.uid, !uid.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
|
||||
print("🔍 认证检查:uid 无效")
|
||||
debugInfo("🔍 认证检查:uid 无效")
|
||||
return .invalid
|
||||
}
|
||||
|
||||
// 检查 ticket 是否有效
|
||||
guard let ticket = accountModel.ticket, !ticket.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
|
||||
print("🔍 认证检查:ticket 无效")
|
||||
debugInfo("🔍 认证检查:ticket 无效")
|
||||
return .invalid
|
||||
}
|
||||
|
||||
// 可选:检查 access token 是否有效
|
||||
guard let accessToken = accountModel.accessToken, !accessToken.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
|
||||
print("🔍 认证检查:access token 无效")
|
||||
debugInfo("🔍 认证检查:access token 无效")
|
||||
return .invalid
|
||||
}
|
||||
|
||||
print("🔍 认证检查:认证有效 - uid: \(uid), ticket: \(ticket.prefix(10))...")
|
||||
debugInfo("🔍 认证检查:认证有效 - uid: \(uid), ticket: \(ticket.prefix(10))...")
|
||||
return .valid
|
||||
}
|
||||
}
|
||||
@@ -545,6 +551,49 @@ struct UserInfoManager {
|
||||
return self == .valid
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Testing and Debugging
|
||||
|
||||
/// 测试认证 header 功能(仅用于调试)
|
||||
/// 模拟用户登录状态并验证 header 添加逻辑
|
||||
static func testAuthenticationHeaders() {
|
||||
#if DEBUG
|
||||
debugInfo("\n🧪 开始测试认证 header 功能")
|
||||
|
||||
// 测试1:未登录状态
|
||||
debugInfo("📝 测试1:未登录状态")
|
||||
clearAllAuthenticationData()
|
||||
let headers1 = APIConfiguration.defaultHeaders
|
||||
let hasAuthHeaders1 = headers1.keys.contains("pub_uid") || headers1.keys.contains("pub_ticket")
|
||||
debugInfo(" 认证 headers 存在: \(hasAuthHeaders1) (应该为 false)")
|
||||
|
||||
// 测试2:模拟登录状态
|
||||
debugInfo("📝 测试2:模拟登录状态")
|
||||
let testAccount = AccountModel(
|
||||
uid: "12345",
|
||||
jti: "test-jti",
|
||||
tokenType: "bearer",
|
||||
refreshToken: nil,
|
||||
netEaseToken: nil,
|
||||
accessToken: "test-access-token",
|
||||
expiresIn: 3600,
|
||||
scope: "read write",
|
||||
ticket: "test-ticket-12345678901234567890"
|
||||
)
|
||||
saveAccountModel(testAccount)
|
||||
|
||||
let headers2 = APIConfiguration.defaultHeaders
|
||||
let hasUid = headers2["pub_uid"] == "12345"
|
||||
let hasTicket = headers2["pub_ticket"] == "test-ticket-12345678901234567890"
|
||||
debugInfo(" pub_uid 正确: \(hasUid) (应该为 true)")
|
||||
debugInfo(" pub_ticket 正确: \(hasTicket) (应该为 true)")
|
||||
|
||||
// 测试3:清理测试数据
|
||||
debugInfo("📝 测试3:清理测试数据")
|
||||
clearAllAuthenticationData()
|
||||
debugInfo("✅ 认证 header 测试完成\n")
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - API Request Protocol
|
||||
|
||||
@@ -93,6 +93,7 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
var urlRequest = URLRequest(url: url)
|
||||
urlRequest.httpMethod = request.method.rawValue
|
||||
urlRequest.timeoutInterval = request.timeout
|
||||
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||
|
||||
// 设置请求头
|
||||
var headers = APIConfiguration.defaultHeaders
|
||||
@@ -113,18 +114,30 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
var requestBody: Data? = nil
|
||||
if request.method != .GET, let bodyParams = request.bodyParameters {
|
||||
do {
|
||||
// 如果需要包含基础参数,则合并
|
||||
var finalBody = bodyParams
|
||||
|
||||
// 如果需要包含基础参数,则先合并所有参数,再统一生成签名
|
||||
if request.includeBaseParameters {
|
||||
// 第一步:创建基础参数实例(不包含签名)
|
||||
var baseParams = BaseRequest()
|
||||
// 生成符合 API rule 的签名
|
||||
|
||||
// 第二步:基于所有参数(bodyParams + 基础参数)统一生成签名
|
||||
baseParams.generateSignature(with: bodyParams)
|
||||
|
||||
// 第三步:将包含正确签名的基础参数合并到最终请求体
|
||||
let baseDict = try baseParams.toDictionary()
|
||||
finalBody.merge(baseDict) { existing, _ in existing }
|
||||
finalBody.merge(baseDict) { _, new in new } // 基础参数(包括签名)优先
|
||||
|
||||
debugInfo("🔐 签名生成完成 - 基于所有参数统一生成: \(baseParams.pubSign)")
|
||||
}
|
||||
|
||||
requestBody = try JSONSerialization.data(withJSONObject: finalBody, options: [])
|
||||
urlRequest.httpBody = requestBody
|
||||
// urlRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
if let httpBody = urlRequest.httpBody,
|
||||
let bodyString = String(data: httpBody, encoding: .utf8) {
|
||||
debugInfo("HTTP Body: \(bodyString)")
|
||||
}
|
||||
} catch {
|
||||
let encodingError = APIError.decodingError("请求体编码失败: \(error.localizedDescription)")
|
||||
APILoadingManager.shared.setError(loadingId, errorMessage: encodingError.localizedDescription)
|
||||
@@ -133,7 +146,7 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
}
|
||||
|
||||
// 记录请求日志,传递完整的 headers 信息
|
||||
// APILogger.logRequest(request, url: url, body: requestBody, finalHeaders: headers)
|
||||
APILogger.logRequest(request, url: url, body: requestBody, finalHeaders: headers)
|
||||
|
||||
do {
|
||||
// 发起请求
|
||||
@@ -226,16 +239,22 @@ struct LiveAPIService: APIServiceProtocol {
|
||||
// 对于 GET 请求,将基础参数添加到查询参数中
|
||||
if request.method == .GET && request.includeBaseParameters {
|
||||
do {
|
||||
// 第一步:创建基础参数实例(不包含签名)
|
||||
var baseParams = BaseRequest()
|
||||
// 为 GET 请求生成签名(合并查询参数)
|
||||
|
||||
// 第二步:基于所有参数(queryParams + 基础参数)统一生成签名
|
||||
let queryParamsDict = request.queryParameters ?? [:]
|
||||
baseParams.generateSignature(with: queryParamsDict)
|
||||
|
||||
// 第三步:将包含正确签名的基础参数添加到查询参数
|
||||
let baseDict = try baseParams.toDictionary()
|
||||
for (key, value) in baseDict {
|
||||
queryItems.append(URLQueryItem(name: key, value: "\(value)"))
|
||||
}
|
||||
|
||||
debugInfo("🔐 GET请求签名生成完成 - 基于所有参数统一生成: \(baseParams.pubSign)")
|
||||
} catch {
|
||||
print("警告:无法添加基础参数到查询字符串")
|
||||
debugWarn("警告:无法添加基础参数到查询字符串")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ struct IDLoginAPIRequest: APIRequestProtocol {
|
||||
// "version": version,
|
||||
// "client_id": clientId,
|
||||
// "grant_type": grantType
|
||||
// ]
|
||||
// ];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,15 +192,15 @@ struct LoginHelper {
|
||||
|
||||
guard let encryptedID = DESEncrypt.encryptUseDES(userID, key: encryptionKey),
|
||||
let encryptedPassword = DESEncrypt.encryptUseDES(password, key: encryptionKey) else {
|
||||
print("❌ DES加密失败")
|
||||
debugError("❌ DES加密失败")
|
||||
return nil
|
||||
}
|
||||
|
||||
print("🔐 DES加密成功")
|
||||
print(" 原始ID: \(userID)")
|
||||
print(" 加密后ID: \(encryptedID)")
|
||||
print(" 原始密码: \(password)")
|
||||
print(" 加密后密码: \(encryptedPassword)")
|
||||
debugInfo("🔐 DES加密成功")
|
||||
debugInfo(" 原始ID: \(userID)")
|
||||
debugInfo(" 加密后ID: \(encryptedID)")
|
||||
debugInfo(" 原始密码: \(password)")
|
||||
debugInfo(" 加密后密码: \(encryptedPassword)")
|
||||
|
||||
return IDLoginAPIRequest(
|
||||
phone: userID,
|
||||
@@ -292,13 +292,13 @@ struct TicketHelper {
|
||||
/// - accessToken: OAuth 访问令牌
|
||||
/// - uid: 用户唯一标识
|
||||
static func debugTicketRequest(accessToken: String, uid: Int?) {
|
||||
print("🎫 Ticket 请求调试信息")
|
||||
print(" AccessToken: \(accessToken)")
|
||||
print(" UID: \(uid?.description ?? "nil")")
|
||||
print(" Endpoint: /oauth/ticket")
|
||||
print(" Method: POST")
|
||||
print(" Headers: pub_uid = \(uid?.description ?? "nil")")
|
||||
print(" Parameters: access_token=\(accessToken), issue_type=multi")
|
||||
debugInfo("🎫 Ticket 请求调试信息")
|
||||
debugInfo(" AccessToken: \(accessToken)")
|
||||
debugInfo(" UID: \(uid?.description ?? "nil")")
|
||||
debugInfo(" Endpoint: /oauth/ticket")
|
||||
debugInfo(" Method: POST")
|
||||
debugInfo(" Headers: pub_uid = \(uid?.description ?? "nil")")
|
||||
debugInfo(" Parameters: access_token=\(accessToken), issue_type=multi")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,13 +389,13 @@ extension LoginHelper {
|
||||
let encryptionKey = "1ea53d260ecf11e7b56e00163e046a26"
|
||||
|
||||
guard let encryptedEmail = DESEncrypt.encryptUseDES(email, key: encryptionKey) else {
|
||||
print("❌ 邮箱DES加密失败")
|
||||
debugError("❌ 邮箱DES加密失败")
|
||||
return nil
|
||||
}
|
||||
|
||||
print("🔐 邮箱DES加密成功")
|
||||
print(" 原始邮箱: \(email)")
|
||||
print(" 加密邮箱: \(encryptedEmail)")
|
||||
debugInfo("🔐 邮箱DES加密成功")
|
||||
debugInfo(" 原始邮箱: \(email)")
|
||||
debugInfo(" 加密邮箱: \(encryptedEmail)")
|
||||
|
||||
return EmailGetCodeRequest(emailAddress: email, type: 1)
|
||||
}
|
||||
@@ -409,14 +409,14 @@ extension LoginHelper {
|
||||
let encryptionKey = "1ea53d260ecf11e7b56e00163e046a26"
|
||||
|
||||
guard let encryptedEmail = DESEncrypt.encryptUseDES(email, key: encryptionKey) else {
|
||||
print("❌ 邮箱DES加密失败")
|
||||
debugError("❌ 邮箱DES加密失败")
|
||||
return nil
|
||||
}
|
||||
|
||||
print("🔐 邮箱验证码登录DES加密成功")
|
||||
print(" 原始邮箱: \(email)")
|
||||
print(" 加密邮箱: \(encryptedEmail)")
|
||||
print(" 验证码: \(code)")
|
||||
debugInfo("🔐 邮箱验证码登录DES加密成功")
|
||||
debugInfo(" 原始邮箱: \(email)")
|
||||
debugInfo(" 加密邮箱: \(encryptedEmail)")
|
||||
debugInfo(" 验证码: \(code)")
|
||||
|
||||
return EmailLoginRequest(email: encryptedEmail, code: code)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user