wiki'd

by JoKeru

Token Authentication in PHP with Redis

In this post I'll show you how to create and use a token based authentication (something like OAuth2 but waaay lighter) in PHP. The token will expire after a certain period of time. In order to keep the token alive, I've also added a heartbeat function on the client side which re-activates the token from time to time.

The flow is like this:
1 - the user logins with valid credentials
2 - the server creates the user auth token (in Redis), sets the TimeToLive (10 minutes) for it, and then returns the token value to the user
3 - a) the heartbeat mechanism is started to keep the token active (when the server receives the heartbeat, the TTL is reset to 10 minutes)
3 - b) all user communication includes the auth token
4 - if the heartbeat is not received on server side, the token will expire and the user session will be closed

Install prerequisites:

\# get redis  
\$ apt-get install redis-server -y  
\# default config for redis is ok  
\$ /etc/init.d/redis-server restart

\# get predis - a flexible and feature-complete Redis client library for
PHP \>= 5.3  
\$ apt-get install git -y  
\$ cd /var/www/  
\$ git clone git://github.com/nrk/predis.git  

Create token:
[cc lang='php']
\$ttl = 600;
\$server_token = md5(time());
require "predis/autoload.php";
try {
\$redis = new Predis\Client(array("scheme" => "tcp", "host" => "127.0.0.1", "port" => 6379));
\$key = \$server_token;
\$redis->set("\$key", "");
\$redis->expire("\$key", \$ttl);
} catch (Exception \$e) {
return _build_response( ERROR, \$e->getMessage()) );
}

Check token:  
[cc lang='php']  
require "libs/predis/autoload.php";  
try {  
\$redis = new Predis\\Client(array("scheme" =\> "tcp", "host" =\>
"127.0.0.1", "port" =\> 6379));  
\$key = \$user\_token;  
if (!\$redis-\>exists("\$key")) {  
return \_build\_response( ERROR, "session expired" );  
}  
} catch (Exception \$e) {  
return \_build\_response( ERROR, \$e-\>getMessage()) );  
}  

Heartbeat:
[cc lang='php']
\$ttl = 600;
require "libs/predis/autoload.php";
try {
\$redis = new Predis\Client(array("scheme" => "tcp", "host" => "127.0.0.1", "port" => 6379));
\$key = \$user_token;
if (\$redis->exists("\$key")) {
\$redis->expire("\$key", \$ttl);
}
} catch (Exception \$e) {
return _build_response( ERROR, \$e->getMessage()) );
}
```

Comments