鉴权、签名中间件验证

 后端

/**
 * 验证后返回
 * @param $request
 * @param \Closure $next
 * @return mixed|\think\response\Json
 */
public function handle($request, \Closure $next)
{
    try {
        # 验证token 、可以直接加在路由后面
        # 验证时间戳
        $this->checkTime();
        # 验证签名
        $this->checkSign();
        return $next($request);
    } catch (Exception $exception) {
        return json($exception->getMessage());
    }
}
/**
 * 验证时间戳
 * @throws Exception
 */
public function checkTime()
{
    $client_time = request()->get('timestamp') ?: request()->post('timestamp');
    if (!is_numeric($client_time)) {
        throw new Exception('时间戳格式不正确');
    }
    if (time() - $client_time > 120) {
        throw new Exception('请求超时');
    }
}
/**
 * 验证签名
 * @throws Exception
 */
public function checkSign()
{
    $client_sign = request()->get('sign') ?: request()->post('sign');
    # 判断是否有签名
    if (!$client_sign) {
        throw new Exception('签名不正确');
    }

    # 判断签名是否正确
    $server_sign = $this->getSign();

    if ($client_sign != $server_sign) {
        throw new Exception('签名不正确');
    }
}
/**
 * 生成签名
 * @return string
 */
public function getSign()
{
    # 获取所有请求的参数
    $params = request()->all();
    # 签名规则
    # 第一步 参与签名的参数不包括签名本身、不包括token
    unset($params['sign']);
    unset($params['token']);
    # 第二步 按照ASCII进行参数排序
    ksort($params);
    $wait_sign = '';
    foreach ($params as $key => $value) {
        $wait_sign .= $key . '=' . $value . '&';
    }
    # 去除多余的& 符号
    $wait_sign = rtrim($wait_sign, '&');
    return md5($wait_sign);
}

 前端生成签名(md5()方法是引入的js文件中的方法)

/**
 * 生成签名
 * @param params
 * @returns {string}
 */
function create_sign(params) {
    let timestamp = Math.ceil((new Date()).getTime() / 1000);
    params['timestamp'] = timestamp;
    let wait_sign = sort_ascii(params)
    params['sign'] = md5(wait_sign);
    return params;
}

/**
 * 按ascii码从小到大排序
 * @param obj
 * @returns {string}
 */
function sort_ascii(obj) {
    let arr = new Array();
    let num = 0;
    for (let i in obj) {
        arr[num] = i;
        num++;
    }
    let sortArr = arr.sort();
    let str = '';             //自定义排序字符串
    for (let i in sortArr) {
        str += sortArr[i] + '=' + obj[sortArr[i]] + '&';
    }
    //去除两侧字符串
    let char = '&'
    str = str.replace(new RegExp('^\\' + char + '+|\\' + char + '+$', 'g'), '');
    return str;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值