我已经读了很多关于这个的文章,但是我还是没有完全理解。
我将来可能会使用现有解决方案的库,但我现在想要理解和实现我自己的系统。
为了无状态和可扩展,我认为我不应该在服务器上存储用户上下文。
主要问题是概念问题,如果我了解系统,我将成功地编写它
我已经测试了在互联网上发现的代码,我已经修改(法国网站参考:http://blog.nalis.fr/index.php?post/2009/09/28/Securisation-stateless-PHP-avec-un-jeton-de-session-(token)-protection-CSRF-en-PHP)。你能告诉我是对还是错吗?
所以要创建一个令牌,我使用这个函数作为参数,用户的数据
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);
}
因此用户可以验证自己并接收一个包含令牌(genericPart +他的数据,编码)和未编码的hisData的数组:
function auth($login, $password)
{
// we check user. For instance, it's 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);
}
然后用户可以发送他的令牌+他未编码的数据,以便检查:
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's 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
我说的对吗?
很抱歉给你发这么长的信息,也很抱歉我的英语。
提前感谢您的帮助!
你的代码中的问题是:你是基于你的整个系统的$_GET
在原来的帖子是基于Cookies..您应该将令牌存储在cookie中(基于您的原始帖子),而不是使用$_GET
顺便说一下;一些调整:
list($tokenDate, $userData) = array_pad(explode("_", $receivedData));
在接下来的代码中,我不知道你如何使用$login,$password
function auth($login, $password)
{
// we check user. For instance, it's 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);
}