tags:

views:

310

answers:

4

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?

A: 

The most straight-forward type for the MySQL field would be varchar(15). This will fit the longest IPV4 addresses, such as 255.255.255.255, without taking up more space then necessary.

In an ideal situation, the IP will be available in the $_SERVER['REMOTE_ADDR'] global. A proxy setup might leave you with the proxy's IP address in that global, in which case you can try your luck with the X-Forwarded-For header:

$headers = apache_request_headers(); 
$xff = $headers["X-Forwarded-For"];

Just make sure to sanitize the X-Forwarded-For value, I've had to add code to deal with values such as unknown and multiple IPs separated by a comma.

I assume you are trying to prevent session hijacking, which can certainly be argued for. I find it annoying though to find out that when I get to the office and mount my laptop, I get logged out of certain sites ;-).

Lauri Lehtinen
IPv6 is on the way. Strongly suggest you design that in now.
Eric J.
+4  A: 

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.

William Leader
Those functions also don't seem to support IPv6. I think the best solution is a blob. I'm surprised MySQL doesn't have a dedicated data type like postgres' inet type.
Artefacto
They do support IPv6, but will return an 8 byte integer instead of a 4 byte integer.
William Leader
as for IPv6 - http://stackoverflow.com/questions/420680/how-to-store-ipv6-compatible-address-in-a-relational-database/420688#420688
dev-null-dweller
I stand corrected.
William Leader
@William Leader I doubt it, since addresses in IPv6 are 128-bit long they don't fit in an 8 byte integer.
Artefacto
A: 

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

Cody Baker
A: 

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 ...

sikas