jsdw_ios/QuickLocation/API/SignPlugin.swift

83 lines
2.7 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
import Moya
import CommonCrypto
/// JiaMiKey MD5
private let jiaMiKeyMD5: String = {
let key = "857d69d374694c1de46486d3bdaaac43"
return SignPlugin.md5(key)
}()
/// Plugin
final class SignPlugin: PluginType {
func prepare(_ request: URLRequest, target: any TargetType) -> URLRequest {
var mutableRequest = request
guard let url = request.url else { return mutableRequest }
let timestamp = String(format: "%.0lf", Date().timeIntervalSince1970)
let nonce = randomString(length: 32)
var queryDict: [String: String] = [
"timestamp": timestamp,
"nonce": nonce
]
// URL query
if let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
let queryItems = components.queryItems {
for item in queryItems {
queryDict[item.name] = item.value ?? ""
}
}
let bodyString: String
if let httpBody = request.httpBody, !httpBody.isEmpty {
bodyString = String(data: httpBody, encoding: .utf8) ?? ""
} else {
bodyString = ""
}
let queryString = sortedQueryString(queryDict)
let signStr: String
if bodyString.isEmpty {
signStr = queryString + "&" + jiaMiKeyMD5
} else {
signStr = queryString + "&" + bodyString + "&" + jiaMiKeyMD5
}
let signature = Self.md5(signStr)
// query query
let signedQuery = queryString + "&signature=" + signature
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
components?.percentEncodedQuery = signedQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
if let newURL = components?.url {
mutableRequest.url = newURL
}
return mutableRequest
}
private func sortedQueryString(_ dict: [String: String]) -> String {
dict
.sorted { $0.key < $1.key }
.map { "\($0.key)=\($0.value)" }
.joined(separator: "&")
}
private func randomString(length: Int) -> String {
let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map { _ in chars.randomElement()! })
}
fileprivate static func md5(_ string: String) -> String {
let cStr = string.cString(using: .utf8)
let length = CC_LONG(strlen(cStr!))
var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
CC_MD5(cStr, length, &digest)
return digest.map { String(format: "%02x", $0) }.joined()
}
}