当用户登录时,我想将他们的IP保存在数据库中。我该怎么办? MySQL字段最适合使用哪种类型? PHP代码如何获得IP看起来像?
我正在考虑将其用作登录/会话内容的额外安全功能。我正在考虑检查用户从数据库登录的IP,用户现在拥有的IP作为检查会话的补充。因此,它首先检查会话,然后检查您是否有有效的IP。
这是一个很好的额外功能吗?还有什么其他方法可以让它更安全?
答案 0 :(得分:9)
查看mysql中的INET_NTOA和INET_ATON函数。它们在点分表示法IP地址之间转换为32位整数。这允许您以4个字节而不是15个字节存储IP。确保使用unsigned int而不是signed int。
答案 1 :(得分:2)
关于William Leader的建议,PHP有两个函数ip2long和long2ip完全正如他所说的那样。
答案 2 :(得分:0)
正如Lauri Lehtinen所说,你使用$_SERVER['REMOTE_ADDR']
来获取IP地址,下面是一个简单的PHP代码......
<?php
$conn = mysql_connect("server","username","password");//server, username and password are your server address and access details
if(!$conn)
die("cannot connect to mysql server" . mysql_error());
mysql_select_db("database Name", $conn);
$sql = "INSERT INTO table_name (IP_Address) VALUES(" . $_SERVER['REMOTE_ADDR'] . ")";
if(!mysql_query($sql,$conn))
die("ERROR: " .mysql_error());
mysql_close($con);
?>
这只是一个示例,只需修改它以满足您的需求......
答案 3 :(得分:0)
TLDR;使用VARBINARY(16)并使用INET6_ATON和INET6_NTOA函数来写入/读取存储在数据库中的$ _SERVER ['REMOTE_ADDR']。
在回答问题之前,最好讨论一下如何获取IP地址。如果将它用于重要的事情(例如安全性检查),则应仅使用$ _SERVER ['REMOTE_ADDR'],因为它是唯一受信任的源(由Web服务器生成,并且通过三种方式保证是TCP / IP握手)...,除非您在本地网络中使用该应用程序...等等。如果是网站,请使用$ _SERVER ['REMOTE_ADDR']获取用户IP。
此IP可以是代理服务器之一。如果原始用户IP位于代理之后,则最终可以通过获取代理服务器(有时)添加的标头来获得原始IP。这是一个101函数:
$ip = filter_var(
array_map("trim",
explode("," ,
$_SERVER['HTTP_CLIENT_IP']??
$_SERVER['HTTP_X_FORWARDED_FOR']??
$_SERVER['HTTP_X_FORWARDED']??
$_SERVER['HTTP_FORWARDED_FOR']??
$_SERVER['HTTP_FORWARDED']??
$_SERVER['REMOTE_ADDR']
)
)[0],
FILTER_VALIDATE_IP);
$ip = $ip!=""?$ip:"Invalid IP";
echo $ip;
但是请注意,任何以HTTP_ *开头的标头都可能被用户伪造(他可以在其中写任何他想写的东西。因此这是不可信的。
话虽如此,如果您将PHP与MySQL / MariaDB结合使用,则可以通过以下方式存储IP(在下面的示例中,我存储IP和登录系统的尝试次数):
CREATE TABLE login_logs_hash(
ip VARBINARY(16) NOT NULL,
PRIMARY KEY(ip) USING HASH,
attempts INT UNSIGNED NOT NULL DEFAULT 1
)ENGINE = MEMORY;
登录失败(无效的用户名和密码)在脚本中的某个位置:
...
$sql = "INSERT INTO login_logs_hash (ip)
VALUES (INET6_ATON('".$_SERVER['REMOTE_ADDR']."'))
ON DUPLICATE KEY UPDATE attempts = attempts+1";
$result = mysqli_query($link, $sql);
...
通过该示例,我最终向您显示答案-最好的列是VARBINARY(16)。它可以同时存储IPv6和IPv4。
重要信息:即使最终您会认为固定列宽更好,也不要将其更改为BINARY(16)。如果按照我的示例,它将无法正确存储IPv4地址。