将IP保存到数据库中

发布于 2024-09-04 06:22:05 字数 214 浏览 4 评论 0原文

当用户登录时,我想将他们的 IP 保存在数据库中。我该怎么做呢? MySQL 字段最适合使用什么类型?获取IP的PHP代码是什么样的?

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

这是一个很好的附加功能吗?我还可以做哪些其他事情来使其更安全?

When a user logs in I want to save their IP in the database. How would I do that? What type is best to use for the MySQL field? How would the PHP code to get IP look like?

I'm thinking of using it as an extra security feature for the login/session stuff. I'm thinking of checking the IP the user logged in with from the DB with the IP the user have now as addition to checking the session. So that it first check the session, and then check if you have a valid IP.

Is that a good extra feature? And what other things can I do to make it more secure?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别再吹冷风 2024-09-11 06:22:05

看一下mysql中的INET_NTOA和INET_ATON函数。它们将点分 IP 地址转换为 32 位整数。这允许您仅用 4 个字节而不是 15 个字节来存储 IP。确保您使用的是无符号整型而不是有符号整型。

Have a look at the INET_NTOA and INET_ATON functions in mysql. They convert between dotted notation IP address to 32 bit integers. This allows you to store the IP in just 4 bytes rather than a 15 bytes. Make sure you use an unsigned int and not a signed int.

与之呼应 2024-09-11 06:22:05

关于 William Leader 的建议,PHP 有两个函数 ip2long 和 long2ip 完全可以实现他所说的功能。

In regards to William Leader's suggestion, PHP has two functions ip2long and long2ip that do exactly what he's talking about.

银河中√捞星星 2024-09-11 06:22:05

正如 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);
?>

这只是一个示例,只需修改它以适合您的情况即可需要...

as Lauri Lehtinen said,you use the $_SERVER['REMOTE_ADDR'] to get the IP-Address, for a simple PHP Code look below ...

<?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);
?>

This is just a sample just modify it to suite your needs ...

涫野音 2024-09-11 06:22:05

TLDR;使用VARBINARY(16)并使用INET6_ATON和INET6_NTOA函数来写入/读取存储在DB中的$_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 地址。

TLDR; Use VARBINARY(16) and use the INET6_ATON and INET6_NTOA functions to write/read $_SERVER['REMOTE_ADDR'] stored in the DB.

Before answering the question, it's good to discuss how to fetch the IP address. If you will use it for something important (eg. security checks), then you should use only $_SERVER['REMOTE_ADDR'] as it is the only trusted source (generated by the web server and guaranteed to be good by the three way TCP/IP handshake)... except if you are using the app in local network... etc. If it is a website, use $_SERVER['REMOTE_ADDR'] to take the user IP.

This IP can be a proxy server one. You can eventually get the original user IP if he is behind a proxy by fetching the headers that the proxy servers (sometimes) add. This is a 101 function for that:

     $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;

HOWEVER note that any header starting with HTTP_* can be faked by the user (he can write there whatever he want. So this is NOT to be trusted.

Having said that, if you are using PHP with MySQL/MariaDB, you can store the IP the following way (in the example below I store the IP and the number of attempts to login to the system):

    CREATE TABLE login_logs_hash(
         ip VARBINARY(16) NOT NULL,
         PRIMARY KEY(ip) USING HASH,
         attempts INT UNSIGNED NOT NULL DEFAULT 1
    )ENGINE = MEMORY;

Somewhere in the script when the login is unsuccessful (invalid username and password):

    ...
    $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);
    ...

By that example I finally show you the answer - the best column is VARBINARY(16). It can store both IPv6 and IPv4.

IMPORANT: do no change it to BINARY(16) even you will be eventually thinking that fixed column width is better. It will not store the IPv4 addresses correctly if you follow my example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文