一个验证token类

本文介绍了一个使用PHP编写的简单验证类,用于生成含有时效性的二维码核销码。通过设置超时时间,可以防止用户将核销码转售他人,确保平台责任。类中包含了生成和验证Token的方法,以及判断是否超时的逻辑,适用于二维码核销场景。
摘要由CSDN通过智能技术生成

新写了一个超级简单的验证类,最近的一个需求用到了生成二维码核销的功能,想着给二维码做一个时效性处理,避免用户投机倒把,把核销码拿去卖给别人,出了问题,又要平台承担责任。

为了避免以后用到,特地写做笔记。

<?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数据,生成二维码给客户,客户拿着二维码,给商户核销,商户扫码就验证二维码数据是否超时和有效。

最后,仅供参考,有问题不负责。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值