PHP API签名

实际普通项目中API签名 主要是参数和有效性验证,这两个基本能满足API的开发验证了。

请求有效性验证
每次请求都带上时间戳timestamp,服务端校验其是否在有效期内。
安全性要求更高的,客户端请求参数加上随机字符串nonce。
服务端redis记录timestamp+nonce并设置有效期。

API签名验证步骤:
1.按照键名对请求参数进行升序排序:ksort;
2.请求参数键名和键值拼接成字符串
3.拼接的串加入秘钥secretKey
4.拼接串md5或sha1后转大写
实现示例

/**
     * url请求参数验证 timestamp+appkey+sign
     * @param   $params timestamp:时间戳 appkey:系统分配给客户端的key nonce:客户端随机字符串 sign:客服端生成的签名
     */
    public function checkSign($params=[])
    {
        if (!($params['timestamp'] && $params['sign'] && $params['appkey'])) {
            echo '非法参数';exit();
        }

        $clientSign = $params['sign'];
        unset($params['sign']);

        //请求有效性--5分钟内
        $minusTime = abs(time()-$params['timestamp']);
        if ($minusTime>300) {
            echo '签名已过期';exit();
        }

        $nonceKey = $params['timestamp'].$params['nonce'];
        if ($this->redis->get($nonceKey)) {
            echo '请求重复';exit();
        }
        $this->redis->set($nonceKey, time(), 300);
        
        $serverSign = $this->genSign($params, self::APP_SECRET_KEY[$params['appkey']);
        if ($clientSign != $serverSign) {
            echo '签名验证失败';exit();
        }

        return true;
    }

    /**
     * @param    array  $params 编码的参数
     * @param    string $secretKey 秘钥
     * @return   string $sign
     */
    function genSign($params=[], $secretKey='')
    {
        $text = '';
        ksort($params);
        foreach ($params as $key => $value) {
            $text .= $key.$value;
        }

        $sign = md5($secretKey.$text.$secretKey);
        $sign = strtoupper($sign);

        return $sign;
    }

访问示例
api/k1=v1&…×tamp=1570600272&sign=signVal

你可能感兴趣的:(PHP)