softsmart / simple-nonce
简单的nonce实现
Requires
- php: >=5.4.0
Requires (Dev)
- phpunit/phpunit: ^6.5
This package is auto-updated.
Last update: 2024-09-26 15:36:01 UTC
README
PHP中的简单nonce实现
这是一个非常简单的nonce实现。使用PSR-2和PSR-4
结构
如果以下任何一项适用于您的项目,则目录结构应遵循行业最佳实践,如下所示。
src/
tests/
vendor/
安装
通过Composer
$ composer require softsmart/simple-nonce
用法
// Generate Nonce $UserID = 1; // This is the user account we're about to delete $action = "deleteUser"; $meta = [$UserID]; // Optionally set configuration at runtime, else use config.inc.php $nonceConfig = ["salt"=>"your-salt", "ttl"=>3600]; $nonceEngine = new \SoftSmart\Utilities\SimpleNonce($nonceConfig); $nonceValues = $nonceEngine->generateNonce($action, $meta); header("Location: ./deleteUser.php?userID=".$userID."&nonce=".$nonceValues["nonce"]."&timeStamp=".$nonceValues["timeStamp"]); // Verify Nonce $UserID = 1; // This is the user account we're about to delete $action = "deleteUser"; $meta = [$UserID]; $result = SimpleNonce::verifyNonce($nonceValues["nonce"], $action, $nonceValues["timeStamp"], $meta); if( ! $Result ) { echo "Nonce failed"; exit(); } echo "Nonce passed, continue....";
测试
$ phpcs -c phpunit.xml
贡献
请参阅CONTRIBUTING和CODE_OF_CONDUCT以获取详细信息。
致谢
许可证
GNU通用公共许可证。有关更多信息,请参阅许可证文件。
问题
问题:为什么需要传递时间戳?
答案:大多数nonce实现的方式是,当它们创建时,nonce和超时时间存储在文件系统或数据库(如db、redis等)中。当使用nonce时,nonce的有效性和其超时时间从数据库中读取。
此nonce系统不在数据库中存储nonce,也不在文件系统中存储未使用的nonce。我们不这样做的原因是在繁忙的网站上这可能会造成相当大的开销。例如,想象一个繁忙的商店,您想向管理员用户在一个页面上列出许多产品。列表中的每个项目可能都有一个编辑按钮以及一个删除按钮。每个按钮都需要自己的nonce。如果我们每页列出50个项目,那么就是100个nonce写入数据库,而这些nonce可能永远不会被使用。
我们的系统在生成nonce时计算出nonce,然后在验证时根据操作、时间戳和元数据重新计算。因为我们没有预先存储,所以我们需要传递时间戳!
问题:如果我们以纯文本形式将时间戳与链接一起传递,什么可以防止恶意用户在URL中更改时间戳?
答案:generateNonce函数将时间戳作为nonce字段的一部分使用。因此,即使恶意用户可以看到时间戳,他们也无法更改它。如果他们尝试更改它,verifyNonce函数将失败。
问题:如果不写入数据库,它是如何知道nonce只被使用过一次的?
答案:我们确实写入一个文本文件。该文本文件以nonce键命名。当验证nonce时,我们检查该文件是否存在。如果它存在,则表示nonce已经被使用,nonce将失败。