Laravel create token api by securing your webhook

  • December 29, 2020
  • 1026

Khi viết api thường chúng ta sẽ nghĩ đến việc dùng jwt token. Nhưng hôm nay mình gặp một yêu cầu generate token bằng hash sh256 nên viết lại để ae gặp phải đỡ bị bỡ ngỡ như mình. Trường hợp mình gặp phải là tạo auth gửi server backend php và ai server sử dụng python. Yêu cầu bên server backend sẽ sử dụng hash sh256 cho tất cả các request body gửi sang server ai, khi tạo xong mã hash sẽ được chèn vào header HTTP_X_EKYC_SIGNATURE.

Tạo token use securing your webhooks

// Tạo token bằng php
public function generateToken(array $data, string $secretKey): string
{
    // sort data
    ksort($data);
    // convert data to request body
    $requestBody = str_replace('\/', '/', json_encode($data));
        
    return hash_hmac('sha256', $requestBody, $secretKey);
}

Call ai server

Laravel sử dụng Illuminate\Support\Facades\Http để call api, bên dưới là code demo server backend call ai server


    /**
     *  Call ai api.
     *
     * @param array $data Data request to ai.
     * @return array
     */
    public function callAi(array $data): array
    {
        $token = $this->generateToken($data, $this->config['secret_key']);
        $aiEndpoint = 'xxxxx';
        $response = Http::withHeaders([
            'Content-Type' => 'application/json',
            'HTTP_X_EKYC_SIGNATURE' => $token,
        ])->post($aiEndpoint, $data);
        if (!$response->ok()) {
            throw new Exception($response->body(), $response->status());
        }

        return $response->json();
    }

Viết 1 middleware để verify token


<?php

namespace Modules\User\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use App\Helpers\Common;
use App\Traits\ResponseTrait;

class UserAuthMiddleware
{
    use ResponseTrait;

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        if (($headerToken = $request->headers->get('HTTP-X-EKYC-SIGNATURE')) == null) {
            return $this->error('Header not set signature', 400);
        }
        $requestToken = generateToken($request->all(), config('api.secret_key'));
        if (!hash_equals($requestToken, $headerToken)) {
            return $this->error('Unauthorized!', 401);
        }
        
        return $next($request);
    }
}

Tài liệu về securing your webhooks