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。
我还建议对请求正文进行百分比编码,以防您的任何值包含任何保留字符。或者使用像Alamofire这样的库,它可以让你摆脱构建格式良好的请求的麻烦。
您的 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 关注
- 129 浏览
添加回答
举报