วันนี้มาปล่อยของครับ มาดูวิธีการยืนยันลายเซ็น Webhook จาก Monoova ก็คือ การยืนยันลายเซ็นของข้อมูลที่ส่งมานั้น เป็นขั้นตอนสำคัญเพื่อป้องกันการปลอมแปลงข้อมูล บทความนี้จะอธิบายขั้นตอนในการยืนยันลายเซ็น Webhook ด้วยภาษา PHP อ่าน API Documentation
1. การดึง Headers จากคำขอ
function get_ds_headers() {
$headers = array();
foreach ($_SERVER as $key => $value) {
if (strpos($key, 'HTTP_') === 0) {
$headers[str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value;
}
}
return $headers;
}
ฟังก์ชัน get_ds_headers() ใช้ในการดึง headers จากคำขอ HTTP ซึ่งประกอบด้วยข้อมูลสำคัญ เช่น ลายเซ็นการยืนยัน (Verification Signature) ที่เราต้องใช้ในการตรวจสอบความถูกต้อง
2. การดึง Payload ของ Webhook
$payload = file_get_contents('php://input');
ขั้นตอนนี้คือการดึงข้อมูล Payload ซึ่งเป็นข้อมูลหลักที่ Webhook ส่งมา คุณจะต้องใช้ข้อมูลนี้ในการยืนยันลายเซ็น
3. การยืนยันลายเซ็นโดยใช้ใบรับรอง (Certificate)
function certificate($path, $verificationSignature, $payload) {
$certificate = file_get_contents("$path/public/v1/certificate");
$signature = base64_decode($verificationSignature);
$certificate_pem = chunk_split(base64_encode($certificate), 64, "\n");
$certificate_pem = "-----BEGIN CERTIFICATE-----\n" . $certificate_pem . "-----END CERTIFICATE-----\n";
$public_key_resource = openssl_get_publickey($certificate_pem);
$verifyResult = openssl_verify($payload, $signature, $public_key_resource, OPENSSL_ALGO_SHA256);
return $verifyResult;
}
ฟังก์ชัน certificate() ทำหน้าที่ตรวจสอบลายเซ็นที่ได้รับจาก Webhook โดยจะใช้ใบรับรอง (Certificate) จากเซิร์ฟเวอร์ของ Monoova มายืนยันข้อมูล
- โหลดใบรับรอง: ใช้ file_get_contents() เพื่อดึงใบรับรองจาก URL ที่กำหนดไว้
- ถอดรหัสลายเซ็น: ใช้ base64_decode() เพื่อถอดรหัสลายเซ็นที่ได้รับมา
- ยืนยันลายเซ็น: ใช้ openssl_verify() เพื่อเปรียบเทียบลายเซ็นที่ได้รับกับลายเซ็นที่สร้างขึ้นจากข้อมูล Payload
4. การบันทึกข้อมูลการตรวจสอบ
function logger($txt, $path = null) {
$log_file = $path ?? "log.txt";
$myfile = fopen($log_file, "a") or die("Unable to open file!");
fwrite($myfile, "\n" . $txt);
fclose($myfile);
}
ฟังก์ชัน logger() ใช้ในการบันทึกผลการยืนยันลายเซ็น เช่น "Signature is valid." หรือ "Signature is invalid." ลงในไฟล์ log(ไฟล์ log แบบประหยัดอ่ะครับ🤣)
5. การจัดการคำขอ POST
if (isset($_POST)) {
try {
$payload = file_get_contents('php://input');
$headers = get_ds_headers();
if (array_key_exists("VerificationSignature", $headers)) {
$verificationSignature = $headers["VerificationSignature"];
$verifyResult = certificate('https://api.m-pay.com.au', $verificationSignature, $payload);
if ($verifyResult === 1) {
// coding...
logger("Signature is valid.");
} elseif ($verifyResult === 0) {
logger("Signature is invalid.");
} else {
logger("Error verifying signature: " . openssl_error_string());
}
}
} catch (Exception $e) {
logger("\nException: " . $e->getMessage() . "\n");
}
header("HTTP/1.1 200 OK");
}
โค้ดส่วนนี้ใช้ในการจัดการคำขอ POST ที่เข้ามา
- ตรวจสอบว่าเป็นคำขอ POST: ตรวจสอบว่ามีข้อมูลส่งเข้ามาหรือไม่
- ดึง Payload และ Headers: ดึงข้อมูล Payload และ headers ของคำขอ
- ยืนยันลายเซ็น: หากมี Verification Signature อยู่ใน headers จะใช้ฟังก์ชัน certificate() เพื่อตรวจสอบลายเซ็น
- บันทึกผลลัพธ์: บันทึกผลลัพธ์การตรวจสอบลายเซ็นลงในไฟล์ log
- ส่งกลับสถานะ 200 OK: หากทุกอย่างผ่านไปด้วยดี ระบบจะส่งกลับสถานะ 200 OK
สรุป
การยืนยันลายเซ็น Webhook ด้วย PHP เป็นกระบวนการที่สำคัญเพื่อให้แน่ใจว่าข้อมูลที่ได้รับมามีความถูกต้องและปลอดภัย การใช้ฟังก์ชันตามที่ได้อธิบายข้างต้นนี้จะช่วยให้การตรวจสอบลายเซ็นเป็นไปอย่างมีประสิทธิภาพ