<?php
declare (strict_types = 1);
namespace app\middleware;
use think\exception\ValidateException;
use think\facade\Validate;
class SignCheck
{
// sign请求验证规则
public static $rule_sign = [
'sign' => 'require',
'devid' => 'require',
'apptype' => 'require',
'time' => 'require|number',
'nonce' => 'require|number|length:6,10',
'version' => 'require',
];
public static $allow_apptype = ['android','ios','web'];
/**
* 处理请求
*
* @param \think\Request $request
* @param \Closure $next
* @return Response
*/
public function handle($request, \Closure $next)
{
try{
$token=$request->header('token');
if($token){
$headers['token'] = $token;
}
$headers['apptype']=$request->header('apptype');
$headers['time']=$request->header('time');
$headers['devid']=$request->header('devid');
$headers['nonce']=$request->header('nonce');
$headers['version']=$request->header('version');
$headers['sign']=$request->header('sign');
//签名参数效验
$this->checkSignParam(self::$rule_sign,$headers);
// 验证签名
// $param = array_merge($headers,$request->param());
$this->checkRequestAuth($headers);
}catch (\Exception $e){
return resjson( $e->getCode(),$e->getMessage() );
}
return $next($request);
}
/**
* 基础参数安全校验
*
* @param $rule
* @param $param
* @throws \Exception
*/
protected function checkSignParam($rule,$param)
{
try {
validate($rule)->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
throw new \Exception($e->getError(), 402);
}
if(!in_array($param['apptype'], self::$allow_apptype)) {
throw new \Exception('非法设备请求', 401);
}
}
/**
* 检查每次app请求的数据是否合法
*
* @param $param
*/
public function checkRequestAuth($param)
{
if(getMillisecond()-$param['time']>(config("common.app_sign_time")*1000)){
throw new \Exception('时间戳已过期!', 400);
}
$sign1=$param['sign'];
unset($param['sign']);
ksort($param);
$stringA=http_build_query($param,'','&',PHP_QUERY_RFC3986);
$stringSignTemp=$stringA."&secret_key=".config('common.secret_key');
$sign=strtoupper(md5($stringSignTemp));
if($sign!=$sign1){
/*$before=request()->header('before');
$str = date('Y-m-d H:i:s').' ';
$str .= 'service sign:'.$sign.' ';
$str .= 'client sign:'.$sign1.' ';
$str .= 'params:'.$stringSignTemp.' ';
$str .= 'before:'.$before.' ';
file_put_contents('sign_error.log',$str.PHP_EOL,FILE_APPEND);*/
throw new \Exception('签名错误', 400);
}
}
}
暂无评论