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 <wenhsing@qq.com>
 */
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 <wenhsing@qq.com>
     *
     * @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 <wenhsing@qq.com>
     *
     * @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 <wenhsing@qq.com>
     *
     * @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,
        ],
    ];

    // 這里省略了其他代碼
}

好了,你的接口就可以進行簡單的接口簽名驗證了。其他類型的驗證,之后再說。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM