I have 2 web servers running PHP and Nginx... And I have 1 Redis Server. I want the web servers to use the Redis database for user login data. This will allow me to scale out the web servers without forcing logged-in users to re-authenticate if/when they hit a new server.
Both PHP/Nginx servers are using Redis for session handling, and they both point to the same Redis database. When I visit either site in my browser it generates a session token and stores it in Redis (creating two Redis keys total).... But what I want is to create a new session when I visit Site #1, store the session in Redis, and have Site #2 recognize me when I visit because it queries Redis (so only one Redis key total).
All 3 of my servers are in AWS, in the same VPC. I'm using internal IP addresses for communication b/w the web servers and Redis (so there is some amount of trust b/w the machines).
I'm obviously missing something here, and it might be the load balancer (which I will implement). But I was attempting to develop a Redis-sharing design with the minimal number of components. Also, I'm not entirely sure the load balancer helps w/ this issue.
Here are the relevant portions of code:
PHP/Nginx Servers: (x2)
(1) /etc/php/7.2/fpm/php.ini
session.save_handler = redis
session.save_path = "tcp://10.xxx.xx.xxx:6379" // both web servers point to the same Redis IP address
(2) /var/www/html/test.php
<?php
ini_set('session.save_handler', 'redis'); // redundant; including for completeness
ini_set('session.save_path', 'tcp://10.xxx.xx.xxx:6379'); // redundant; including for completeness
session_name('FOOBAR');
session_start();
echo nl2br(
'<pre>' . session_save_path() . '</pre>' . PHP_EOL
);
echo nl2br(
'Running PHP version: ' . phpversion() . PHP_EOL
);
if (!array_key_exists('visit', $_SESSION)) {
$_SESSION['visit'] = 0;
}
$_SESSION['visit']++;
echo nl2br(
'You have been here ' . $_SESSION['visit'] . ' times.'
);
Redis Server: (x1)
(3) /etc/redis/redis.conf
bind 0.0.0.0
When I hit the test.php page for both sites, they successfully generate and store their own session in the Redis database. And they correctly increment their respective session token... But I want these web servers to share the Redis session data b/w them, so they "remember" all logged-in users (even if it's the user's first time hitting a given web server).
Thanks!
EDIT: I also attempted to manually query Redis for logged-in user data. This yielded similar results to test.php above. Each website ended up creating and managing its own session token.
PHP/Nginx Servers: (x2)
(4) /var/www/html/redis-check.php
<?php
$cookie = "PHPREDIS_SESSION:" . $_COOKIE['FOOBAR'];
// Connecting to Redis server on localhost
$redis = new Redis();
$redis->connect('10.xxx.xx.xxx', 6379);
echo "Connection to server sucessfully";
echo '<br />';
// Check if cookie value exists in Redis
$seenuser = $redis->get($cookie);
if( !empty($seenuser) )
{
echo 'Hello, old friend!<br />';
echo '<br />';
echo 'Cookie Value: ' . $cookie;
echo '<br />';
echo 'Session Value: ' . $seenuser;
}
else
{
// This is a new user, so create a new session
ini_set('session.save_handler', 'redis'); // redundant; including for completeness
ini_set('session.save_path', 'tcp://10.xxx.xx.xxx:6379'); // redundant; including for completeness
session_name('FOOBAR');
session_start();
if (!array_key_exists('visit', $_SESSION))
{
$_SESSION['visit'] = 0;
}
$_SESSION['visit']++;
$cookie = "PHPREDIS_SESSION:" . $_COOKIE['FOOBAR'];
$seenuser = $redis->get($cookie);
echo 'New Login<br />';
echo '<br />';
echo 'Cookie Value: ' . $cookie;
echo '<br />';
echo 'Session Value: ' . $seenuser;
}