接口校验思路:
在对外提供接口时,我们一定要注意到数据的安全问题。如果可以建议使用HTTPS,但是在接口安全方面,还是建议大家对接口数据进行数据签名,防止中途数据被串改。签名的主要思想如下:
1、首先要定义如下三个字段:
当前时间戳:防止接口一直被刷 签名字段:主要是服务端用来进行对比数据是否一致 签名秘钥: 必须将当前时间戳和签名秘钥参数追加到传递进来的参数中。
2、对所有参数按照键进行升序排列
3、将第二步排列好的参数按照key=value&key=value进行拼接
4、将第三步拼接好的参数与时间戳、秘钥拼接
5、将第四步的字符串进行md5进行加密后转大写,生成对应的签名字符串
6、将第五步的签名数据追加到传递进来的参数中
7、将第六步的数据进行签名对比
实例:
<?php
namespace App\Http\Middleware;
use App\Http\Constants\ApiStatus;
use App\Http\Controllers\Controller;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/**
* 接口签名校验
* Class SignMiddleware
* @package App\Http\Middleware
*/
class SignMiddleware
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
try {
$miyuSign = $request->header("miyu-sign");
$time = $request->header("miyu-time");
if (empty($sign) || empty($time)) {
return Controller::responseError(ApiStatus::ILLEGAL_REQUEST);
}
# 时间有效性校验
$currentTime = time();
if ($currentTime - $time >= 300 || $currentTime - $time < -300) {
return Controller::responseError(ApiStatus::TIME_EXCEPT);
}
if ($request->method() == "POST") {
$data = $request->post();
} elseif ($request->method() == "GET") {
$data = $request->all();
}
ksort($data);
$sign = md5(urldecode(http_build_query($data)) . "&time=" . $time . '&token=111111111');
if ($sign !== $miyuSign) {
return Controller::responseError(ApiStatus::ILLEGAL_REQUEST);
}
} catch (\Exception $e) {
Log::debug($e->getMessage());
return Controller::responseError(ApiStatus::ILLEGAL_REQUEST);
}
return $next($request);
}
}
注意事项
1、假如是客户端请求接口,就需要多想一步了。假如把 秘钥 硬编码到客户端,会有反编译的风险,特别是 android 。可以在客户端登陆验证成功后,返回给客户端的信息中带上 秘钥(当然,返回的数据也可能被拦截,真是防不胜防啊。。。)。特别说明一下,在 android 开发中,假如硬要把 秘钥 硬编码,建议把 appsecret 放到 NDK 中编译成 so 文件, app 启动后去读取。