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 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);
}
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();
}
<?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