PHP: Understanding and Implementing a Token Authentication System
I've read a lot about this, but I still don't fully understand it.
I may use the library of an existing solution in the future, but I want to understand and implement my own system right now.
To be stateless and scalable, I think I shouldn't be storing user context on the server.
The main problem is the concept, if I understand the system I can manage to code it
I checked the code I found on the internet which I changed (French ref site: http://blog.nalis.fr/index.php?post/2009/09/28/Securisation-stateless-PHP-avec-un-jeton- de-session- (token) -protection-CSRF-en-PHP ). Can you tell me if this is correct or if I don't understand?
So, to create a token, I use this function, which takes user data as parameters
define('SECRET_KEY', "fakesecretkey");
function createToken($data)
{
/* Create a part of token using secretKey and other stuff */
$tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"]; // It can be 'stronger' of course
/* Encoding token */
$token = hash('sha256', $tokenGeneric.$data);
return array('token' => $token, 'userData' => $data);
}
This way the user can authenticate himself and get an array that contains the token (genericPart + its data, encoded) and hisData, not encoded:
function auth($login, $password)
{
// we check user. For instance, it ok, and we get his ID and his role.
$userID = 1;
$userRole = "admin";
// Concatenating data with TIME
$data = time()."_".$userID."-".$userRole;
$token = createToken($data);
echo json_encode($token);
}
Then the user can send me their token + its unencoded data to check:
define('VALIDITY_TIME', 3600);
function checkToken($receivedToken, $receivedData)
{
/* Recreate the generic part of token using secretKey and other stuff */
$tokenGeneric = SECRET_KEY.$_SERVER["SERVER_NAME"];
// We create a token which should match
$token = hash('sha256', $tokenGeneric.$receivedData);
// We check if token is ok !
if ($receivedToken != $token)
{
echo 'wrong Token !';
return false;
}
list($tokenDate, $userData) = explode("_", $receivedData);
// here we compare tokenDate with current time using VALIDITY_TIME to check if the token is expired
// if token expired we return false
// otherwise it ok and we return a new token
return createToken(time()."#".$userData);
}
$check = checkToken($_GET['token'], $_GET['data']);
if ($check !== false)
echo json_encode(array("secureData" => "Oo")); // And we add the new token for the next request
I'm right?
Sorry for this long post and sorry for my english.
Thanks in advance for your help!
source to share
The problem is in your code: you are basing the whole system on $_GET
in the original cookie based message. You should store the token in cookies (based on your original post instead of using $_GET
Btw; a few tweaks:
list($tokenDate, $userData) = array_pad(explode("_", $receivedData));
In the following code, I cannot see how you are using $login,$password
function auth($login, $password)
{
// we check user. For instance, it ok, and we get his ID and his role.
$userID = 1;
$userRole = "admin";
// Concatenating data with TIME
$data = time()."_".$userID."-".$userRole;
$token = createToken($data);
echo json_encode($token);
}
source to share