1 回答
TA貢獻1934條經驗 獲得超2個贊
幾點觀察:
您的 Swift 代碼沒有將請求發送到服務器。您可能會執行以下操作:
var request = URLRequest(url: URL(string:"https://MY_URL.com/registerPushApple.php")!)
request.httpBody = "key=MY_KEY&token=\(token)".data(using: .utf8)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
// OK, if you got here, the server successfully responded, but you now
// need to parse it with `JSONDecoder` and make sure there weren’t any
// SQL errors reported. But I’m just going to print the response JSON for now:
print(String(data: data, encoding: .utf8))
}
task.resume()
筆記:
這是一個POST請求;
我們在httpBody請求中發送我們的數據,而不是 URL;和
我們正在執行請求resume。
我還建議對請求正文進行百分比編碼,以防您的任何值包含任何保留字符?;蛘呤褂孟馎lamofire這樣的庫,它可以讓你擺脫構建格式良好的請求的麻煩。
您的 PHP 代碼不會檢查是否INSERT成功,如果沒有,則以足夠的信息進行響應,以便您診斷正在發生的事情。例如:
<?php
header('Content-type: application/json');
// You didn’t send IP in your request, so you won’t find it in `$_GET` or `$_POST`
// Perhaps https://stackoverflow.com/a/2031935/1271826
function get_ip_address(){
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
if (array_key_exists($key, $_SERVER) === true){
foreach (explode(',', $_SERVER[$key]) as $ip){
$ip = trim($ip); // just to be safe
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
return $ip;
}
}
}
}
}
$mysqli = new mysqli('localhost', 'user', 'pwd', 'db');
// check connection
if ($mysqli->connect_errno) {
echo json_encode(array('success' => false, 'message' => $mysqli->connect_error, 'sqlerrno' => $mysqli->connect_errno));
exit();
}
$mysqli->set_charset('utf8');
// perform the insert
$device_ip = get_ip_address();
$device_token = $_POST['token'];
$key = $_POST['key'];
$sql = 'INSERT INTO device_info (date, device_ip, device_token, key) VALUES (NOW(), ?, ?, ?)';
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param('sss', $device_ip, $device_token, $key);
if (!$stmt->execute())
$response = array('success' => false, 'message' => $mysqli->error, 'sqlerrno' => $mysqli->errno, 'sqlstate' => $mysqli->sqlstate);
else
$response = array('success' => true);
$stmt->close();
} else {
$response = array('success' => false, 'message' => $mysqli->error, 'sqlerrno' => $mysqli->errno, 'sqlstate' => $mysqli->sqlstate);
}
$mysqli->close();
echo json_encode($response);
?>
筆記:
您希望將您的值綁定到?SQL 中以防止 SQL 注入攻擊(或使用real_escape_string);和
您想檢查插入是否成功并返回有意義的 JSON 響應,無論成功與否。
現在,我只是把它刪掉了,所以請原諒任何印刷錯誤。但希望這能給你基本的想法。
顯然,您不應該只打印返回的 JSON,而是對其進行解析JSONDecoder并查看結果是否有錯誤。
同樣,您的 PHP 可能應該對請求中的參數進行一些優雅的檢查,如果沒有,則返回漂亮的 JSON 錯誤響應。但希望這能讓你朝著正確的方向前進。
你說:
我還想發送設備的 IP 以匹配我應用的當前用戶。
不,您不希望設備在請求中添加其 IP 號碼,因為設備只會知道其本地 IP 號碼(例如,如果在 wifi 上,它通常是 192.168.0.x 之類的東西,許多用戶可能有各自的 LAN 上相同的本地 IP 號)。顯然,就服務器而言,這通常是沒有意義的。您應該讓 PHP 從它收到的請求中提取 IP 號,如上所示。
最重要的是,無論如何,我認為IP號碼不是驗證用戶的好方法。如果您走進一家咖啡館并使用他們的 wifi:IP 號碼已更改。您打開 VPN:IP 號碼再次更改。您失去 Internet 連接并重新連接:IP 號碼可能再次更改。最重要的是,IP 編號(即使您讓服務器獲取它而不是要求設備找出它)可能會發生變化,并且不是驗證用戶的好方法。
不要誤會我的意思:我不認為捕獲 IP 號碼一定是一個壞主意。但僅供參考。如果您想驗證用戶,通常還有其他更好的方法可以做到這一點。
- 1 回答
- 0 關注
- 163 瀏覽
添加回答
舉報
