iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Modern Web

工作後才知道的後端 30 件小事系列 第 16

Laravel Middleware 實作 Signature Verification

延續昨天,我們來看可以怎麼在 Laravel 框架下實作簽證的驗證。

What is middleware?

有點像 pipe 可以一個串一個去處理請求。例如,我們可以讓請求都先做 authentication 通過後才做進一步處理。當然我們也可以自定義一些客製化的流程,例如 verify signature。

範例

以下就以驗證簽章為例來實作 Laravel middleware

  1. 新增 middleware
$ php artisan make:middleware VerifySignature
  1. 驗證的具體邏輯
class VerifySignature
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // 對方的 signature 放在 header
        $signature = $request->headers->get('X-Signature');
        $body = $request->getContent();
        
        if ($signature !== hash_hmac('sha256', $body, config('klk.secret'))) {
            // 如果驗證失敗簡單回覆個訊息
            $body = [
                "code" => 401,
                "message" => "signature error",
                "timestamp" => date('Y-m-d H:i:s')
            ];
            return response(json_encode($body), 401)->header('Content-Type', 'application/json');
        }

        return $next($request);
    }
}
  1. 註冊自定義 middleware
// 編輯 App\Http\Kernel

/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
    // 新增我們的 middleware,key 看要取什麼名字都可以
    'verify.signature' => \App\Http\Middleware\VerifySignature::class
];
  1. 最後在 web routes 使用

可以直接這樣使用

Route::middleware('verify.signature')->post('webhook/handler', 'WebhooksController@handle');

也可以用 group,因為可能多支 webhook 都要通過同樣的簽章驗證

Route::middleware('verify.signature')->group(function () {
    // Route::post();
    // Route::post();
    // Route::post();
    // ...
});

注意!上面 routes 寫法是 Laravel 7,最新的寫法請參閱官方文件

Reference


上一篇
什麼是 Webhook Signature
下一篇
Postman pre-request script & tests
系列文
工作後才知道的後端 30 件小事20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言