新写了一个超级简单的验证类,最近的一个需求用到了生成二维码核销的功能,想着给二维码做一个时效性处理,避免用户投机倒把,把核销码拿去卖给别人,出了问题,又要平台承担责任。
为了避免以后用到,特地写做笔记。
<?php
class Token
{
protected $secret; //这个秘钥很重要
public function __construct($secret)
{
$this->secret = $secret;
}
public function getToken($arr)
{
$arr['time'] = strval(time());
$arr['rand_str'] = bin2hex(random_bytes(16));
$arr['sign'] = $this->getSign($arr);
return $arr;
}
/**
* 验证
* @param [type] $arr 待验证的数据
* @param int|integer $time 超时时间,0表示永不超时
* @return [type] [description]
*/
public function verifyToken($arr, int $time = 1800)
{
//如果$time大于0 ,表示需要验证是否超时
if ($time > 0) {
if ($this->isOverTime($arr, $time)) {
throw new \Exception("verify over time", 1);
}
}
$sign = $arr['sign'];
unset($arr['sign']);
if ($sign === $this->getSign($arr)) {
return true;
}
throw new \Exception("verify error", 1);
}
/**
* 判断是否超时
* @param [type] $arr [description]
* @param integer $time [description]
* @return boolean [description]
*/
protected function isOverTime($arr, int $time)
{
$now = time();
//如果没有定义time字段,直接超时
if (!isset($arr['time'])) {
return true;
}
//当前时间-验证时间 大于 $time,就算过期了
if ($now - intval($arr['time']) > $time) {
return true;
}
return false;
}
/**
* 生成签名
* @param [type] $arr [description]
* @param [type] $secret [description]
* @return [type] [description]
*/
protected function getSign($arr)
{
ksort($arr);
$str = '';
foreach ($arr as $k => $v) {
$str .= sprintf("%s=%s&", $k, $v);
}
$str .= sprintf("%s=%s", 'secret', $this->secret);
return sha1($str);
}
}
$secret = '123';
$token = new Token($secret);
$arr = ['order_no' => '20210831222512345'];
//1. 用来生成token后,给到客户端或者生成二维码,一段时间内有效,超时不候
$arr = $token->getToken($arr);
echo json_encode($arr);
//2. 下面是用来验证当初给客户的数据或者二维码的有效和是否超时
try {
$arr = array(
'order_no' => '20210831222512345',
'time' => '1630423797',
'rand_str' => '6b859d0963aed6b2e10f6d5ec232a508',
'sign' => 'd4673a3e4d22792d6f463235773d146a372fb4a6',
);
$token->verifyToken($arr, 60);
} catch (\Exception $e) {
echo $e->getMessage();
}
使用方式很简单,就拿着订单号生成一串json数据,生成二维码给客户,客户拿着二维码,给商户核销,商户扫码就验证二维码数据是否超时和有效。
最后,仅供参考,有问题不负责。