多系统对接-签名校验案例
多系统对接-签名校验案例
config/Sign.php
<?php
// 第三方平台调用『当前系统』接口的签名密钥
return [
// 签名生命周期设置,单位秒
'sign_ttl' => env('SIGN_TTL', 600),
// 签名类型
'sign_type_xxx' => 'xxx', // xxx系统
'sign_type_test' => 'test', // test系统
// 密钥
'sign_type_secret' => [
'xxx' => env('SIGN_SECRET_XXX', 'test_123456'),
'test' => env('SIGN_SECRET_TEST', 'test_123456'),
],
];
app/Services/AuthSign.php
<?php
namespace App\Services;
// 第三方平台请求的签名校验
class AuthSign
{
/**
* 签名校验
* @param string $signType 签名类型,对接哪个第三方系统的标识
* @param string $sign 签名
* @param int $requestTime 请求时间戳
* @return array
*/
public static function checkSign(string $signType, string $sign, int $requestTime): array
{
// 签名类型:新增对外接口签名类型时,需要去配置新的签名类型和密钥
$signSecret = config('sign.sign_type_secret')[$signType] ?? '';
if ($signSecret == '') {
return ['result' => false, 'msg' => '该签名类型还没配置'];
}
if ($sign != md5("{$requestTime}-{$signType}-{$signSecret}")) {
return ['result' => false, 'msg' => '签名有误'];
}
$currentTime = time();
if ($currentTime < $requestTime || ($currentTime-$requestTime) > config('sign.sign_ttl')) {
return ['result' => false, 'msg' => '签名已过期'];
}
return ['result' => true, 'msg' => '签名校验成功'];
}
/**
* 生成签名
* @param string $signType 签名类型,对接哪个第三方系统的标识
* @return array
*/
public static function getSign(string $signType): array
{
$signSecret = config('sign.sign_type_secret')[$signType] ?? '';
if ($signSecret == '') {
return ['result' => false, 'msg' => '该签名类型还没配置'];
}
$requestTime = time();
return ['result' => true, 'time' => $requestTime, 'sign' => md5("{$requestTime}-{$signType}-{$signSecret}")];
}
}
app/Http/Middleware/AuthSignTest.php
<?php
namespace App\Http\Middleware;
use App\Facades\Response;
use Symfony\Component\HttpFoundation\Response as FoundationResponse;
use Closure;
// 『test系统』请求『当前系统』接口的签名校验
class AuthSignTest
{
public function handle($request, Closure $next)
{
$sign = $request->header('sign') ?: '';
$time = $request->header('time') ? : '';
if (empty($sign) || empty($time)) {
return Response::fail('传参有误', [], FoundationResponse::HTTP_UNAUTHORIZED);
}
$signData = \App\Services\AuthSign::checkSign(config('sign.sign_type_test'), $sign, (int)$time);
if (!$signData['result']) {
return Response::fail("sign校验失败:{$signData['msg']}", [], FoundationResponse::HTTP_UNAUTHORIZED);
}
return $next($request);
}
}
app/Http/Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
// 注册中间件
protected $routeMiddleware = [
'auth.test' => \App\Http\Middleware\AuthSignTest::class,
];
}
routes/api_sign.php
<?php
// 路由使用签名做校验
Route::group(['prefix' => 'mini', 'middleware' => ['auth.test', 'request.log'], 'namespace' => 'test'], function () {
Route::put('xxx', 'SignController@setXXX');
});
本作品采用《CC 协议》,转载必须注明作者和本文链接