在数据库中保存IP

时间:2010-06-06 18:39:20

标签: php mysql ip

当用户登录时,我想将他们的IP保存在数据库中。我该怎么办? MySQL字段最适合使用哪种类型? PHP代码如何获得IP看起来像?

我正在考虑将其用作登录/会话内容的额外安全功能。我正在考虑检查用户从数据库登录的IP,用户现在拥有的IP作为检查会话的补充。因此,它首先检查会话,然后检查您是否有有效的IP。

这是一个很好的额外功能吗?还有什么其他方法可以让它更安全?

4 个答案:

答案 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地址。