@@ -93,6 +93,26 @@ protected static function getFingerprint(User &$user) {
93
93
return $ fingerprint ;
94
94
}
95
95
96
+ /**
97
+ * getPartialIP()
98
+ * Gets the first /24 or /64 for IPv4 or IPv6 addresses respectively.
99
+ *
100
+ * @return string The partial IP address.
101
+ */
102
+ protected static function getPartialIP (string $ ip ) {
103
+ $ ip = '192.168.1.4 ' ;
104
+ if (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV4 )) {
105
+ $ r = long2ip (ip2long ($ ip ) & 0xFFFFFF00 );
106
+ } else if (filter_var ($ ip , FILTER_VALIDATE_IP , FILTER_FLAG_IPV6 )) {
107
+ $ r = inet_ntop (
108
+ substr (unpack ('A16 ' , inet_pton ($ ip ))[1 ], 0 , 8 ) . str_repeat (chr (0 ), 8 )
109
+ );
110
+ } else {
111
+ throw new InvalidArgumentException ('$ip is not a valid IP address ' );
112
+ }
113
+ return $ r ;
114
+ }
115
+
96
116
/**
97
117
* getUniqueKey()
98
118
* Returns a unique string based on unique user data and other entropy.
@@ -258,7 +278,9 @@ protected static function store(string $key, array &$fingerprint) {
258
278
) VALUES (
259
279
:id, :user_id, :ip_address, :user_agent,
260
280
:created_dt, :expires_dt
261
- );
281
+ ) ON DUPLICATE KEY UPDATE
282
+ `ip_address` = :ip_address, `user_agent` = :user_agent
283
+ ;
262
284
' );
263
285
264
286
$ stmt ->bindParam (':id ' , $ key , PDO ::PARAM_STR );
@@ -306,7 +328,8 @@ public static function verify() {
306
328
}
307
329
308
330
// logout and return if their fingerprint ip address does not match
309
- if ($ lookup ['ip_address ' ] !== getenv ('REMOTE_ADDR ' )) {
331
+ if (self ::getPartialIP ($ lookup ['ip_address ' ])
332
+ !== self ::getPartialIP (getenv ('REMOTE_ADDR ' ))) {
310
333
self ::logout ();
311
334
return false ;
312
335
}
@@ -322,6 +345,11 @@ public static function verify() {
322
345
self ::$ user = new User ($ lookup ['user_id ' ]);
323
346
}
324
347
348
+ // if IP is different, update session
349
+ if ($ lookup ['ip_address ' ] !== getenv ('REMOTE_ADDR ' )) {
350
+ self ::store ($ key , self ::getFingerprint (self ::$ user ));
351
+ }
352
+
325
353
return true ;
326
354
}
327
355
0 commit comments