gpt4 book ai didi

php - PHP 中跨服务器通信的一次性 CSRF token 生成和验证

转载 作者:行者123 更新时间:2023-12-04 18:19:00 34 4
gpt4 key购买 nike

我进行了很多搜索,试图找到适合我的目的的东西,但是大多数解决方案都围绕着与 session 数据一起工作的 CSRF token 。我的目的需要“基于时间的” token 进行跨服务器通信。

我有 Server A需要接收和验证通过 POST 从 Server B 发送给它的 token . token 需要在 Server B 上生成通过使用 key 进行散列。 Server A必须验证相同。现在,问题是 token 需要限制为一次性使用(可能?)并且应该根据时间过期(比如 10 分钟的生命周期)。因为,这是跨服务器通信,我不能使用 session 。

恐怕我不能使用数据库或 session 来存储/验证 token 。任何代码示例都会有所帮助。

这在 PHP 环境中是必需的。

最佳答案

您可以做的是向 token key 添加时间戳,就像它创建时加上请求者 IP 一样,然后在您解密 key 时检查时间是否介于允许的时间或允许的 IP 地址之间。

固定IP的例子:

<?php
class csrf_check {

const SALT = '_SECRET_';

public function create_api_key()
{
return base64_encode($this->encrypt(time().'|'.$_SERVER['REMOTE_ADDR'])); // !change if you dont want IP check
}

public function check_api_key($key, $timeout = 5)
{
if (empty($key)) exit('Invalid Key');

$keys = explode('|', $this->decrypt(base64_decode($key)));

return (
isset($key, $keys[0], $keys[1]) &&
$keys[0] >= (time() - $timeout) &&
$keys[1] == $_SERVER['REMOTE_ADDR'] // !change if you dont want IP check
);
}

public function encrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
// hash
$key = hash('sha256', $key);
// create iv - encrypt method AES-256-CBC expects 16 bytes
$iv = substr(hash('sha256', $secret), 0, 16);
// encrypt
$output = openssl_encrypt($string, $method, $key, 0, $iv);
// encode
return base64_encode($output);
}

public function decrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
// hash
$key = hash('sha256', $key);
// create iv - encrypt method AES-256-CBC expects 16 bytes
$iv = substr(hash('sha256', $secret), 0, 16);
// decode
$string = base64_decode($string);
// decrypt
return openssl_decrypt($string, $method, $key, 0, $iv);
}
}

$csrf = new csrf_check();

//start example

$do = filter_input(INPUT_GET, 'do');
$key = filter_input(INPUT_GET, 'key');

switch ($do) {
//example.com?do=get - a key for the request
case "get": {
$key = $csrf->create_api_key();
echo '<a href="?do=check&key='.urlencode($key).'">Check Key ('.$key.')</a>';
} break;

//example.com?do=check - a key for the request
case "check": {
//key only lasts 30 secs & validate key passed
//example.com?do=check&key=MEV6NXk4UjVRQXV5Qm1CMjBYa3RZZUhGd2M0YnFBUVF0ZkE5TFpNaElUTT0=

echo 'Key ' . ($csrf->check_api_key($key, 30) ? 'valid' : 'invalid');
echo '<br><a href="?do=get">Get new key</a>';
} break;

default: {
echo '<a href="?do=get">Get Key</a>';
} break;
}

关于php - PHP 中跨服务器通信的一次性 CSRF token 生成和验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11084795/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com