Laravel 简单接口签名验证
在做接口开发的时候,有时候需要提高一些接口安全性方面的工作,比如给接口添加签名等等。本文主要是我自己以前用过的接口签名的方式,放出来让大家见笑见笑。
MD5版
为了实现简单的MD5签名验证,我主要分三步走。
1. 创建文件
打开命令行,运行命令创建中间件。
php artisan make:middleware VerifyApiSign
创建成功后,可以在App\Http\Middleware
目录下找到它。
2. 撸代码
不会撸代码没关系,这里可以使用魔法:选中内容,然后Ctrl+C
→打开VerifyApiSign.php
文件→Ctrl+V
。嗯,保存退出。
<?php
namespace App\Http\Middleware;
use Carbon\Carbon;
use Closure;
/**
* 接口签名
*
* @author Wenhsing
*/
class VerifyApiSign
{
// 忽略列表
protected $except = [
//
];
// 时间误差
protected $timeError = 5;
// 密钥
protected $secretKey = '';
// 签名字段
protected $signField = 'sign';
public function __construct()
{
$this->secretKey = config('auth.api_sign.secret_key', '');
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (
$this->inExceptArray($request)
|| ($this->allowTimestamp($request) && $this->signMatch($request))
) {
return $next($request);
}
throw new \Exception('Signature error');
}
/**
* 判断当前请求是否在忽略列表中
*
* @author Wenhsing
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function inExceptArray($request)
{
foreach ($this->except as $except) {
if ($except !== '/') {
$except = trim($except, '/');
}
if ($request->fullUrlIs($except) || $request->is($except)) {
return true;
}
}
return false;
}
/**
* 判断用户请求是否在对应时间范围
*
* @author Wenhsing
*
* @param \Illuminate\Http\Request $request
* @return boolean
*/
protected function allowTimestamp($request)
{
$queryTime = Carbon::createFromTimestamp($request->query('timestamp', 0));
$lfTime = Carbon::now()->subSeconds($this->timeError);
$rfTime = Carbon::now()->addSeconds($this->timeError);
if ($queryTime->between($lfTime, $rfTime, true)) {
return true;
}
return false;
}
/**
* 签名验证
*
* @author Wenhsing
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function signMatch($request)
{
$data = $request->query();
// 移除sign字段
if (isset($data['sign'])) {
unset($data['sign']);
}
ksort($data);
$sign = '';
foreach ($data as $k => $v) {
if ($this->signField !== $k) {
$sign .= $k . $v;
}
}
if (md5($sign . $this->secretKey) === $request->query($this->signField, null)) {
return true;
}
return false;
}
}
3. 修改配置文件
打开config/auth.php
修改配置文件,在配置后面添加我们的接口签名验证相关参数
<?php
return [
// 这里省略了一些代码
/*
|--------------------------------------------------------------------------
| Api Signature configuration
|--------------------------------------------------------------------------
*/
'api_sign' => [
// 你的密钥串
'secret_key' => env('API_SIGN_SECRET_KEY', ''),
],
];
打开App\Http\Kernel.php
文件,在路由中间件组中的api
字段中添加我们之前创建的中间件
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
// 这里省略了其他代码
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
// 这里省略了其他代码
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
// 接口签名中间件
\App\Http\Middleware\VerifyApiSign::class,
],
];
// 这里省略了其他代码
}
好了,你的接口就可以进行简单的接口签名验证了。其他类型的验证,之后再说。。。