การพิสูจน์ตัวตนบน PHP (HTTP Authentication with PHP)

ในการใช้งาน API บน PHP เรามักจะพบเห็นการส่ง Token ไปกับ Request ของ PHP ด้วยวิธีการต่างๆนาๆ วันนี้ผมจะมาพูดถึงวิธีการรับค่าการพิสูจน์ตัวตน (HTTP Authentication) เหล่านั้นด้วย PHP

บทความนี้ผมจะเน้นไปที่วิธีการรับค่า Authentication ที่ส่งมาด้วย PHP นะครับ ส่วนกระบวนการนำค่าที่รับได้ไปตรวจสอบความถูกต้องผมจะไม่ได้กล่าวถึงในบทความนี้ ซึ่งโดยปกติก็จะเป็นการตรวจสอบคล้ายๆกับการตรวจสอบการ Login ทั่วๆไป

สำหรับการ Authentication ด้วย วิธีพื้นฐาน (Basic) เราสามารถรับค่า Username ได้ที่ตัวแปร $_SERVER['PHP_AUTH_USER'] และ Password ได้ที่ $_SERVER['PHP_AUTH_PW']; ดังตัวอย่าง
เราสามารถทำการส่งค่า Authorization ผ่าน header ของ PHP ได้ด้วย cURL หรือถ้าตามตัวอย่างนี้ส่งผ่านส่วนขยายของ Chrome ที่ชื่อ Advanced REST client ด้วย พารามิเตอร์ Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= (หรือ username+password) และสามารถรับค่าที่ส่งมาได้ที่ตัวแปร  $_SERVER['PHP_AUTH_USER']; และ $_SERVER['PHP_AUTH_PW']; บน PHP ซึ่ง PHP จะทำการแยกค่าที่ส่งมาออกมาเป็น Username และ Password ให้อัตโนมัติ
<?php
$username = $_SERVER['PHP_AUTH_USER']; // username
$password = $_SERVER['PHP_AUTH_PW']; // password

ซึ่ง เราสามารถนำ $username และ $password ที่ได้ไปผ่านกระบวนการตรวจสอบรหัผ่าน (เช่น Login) ได้เลย
หมายเหตุ จากรูปจะเห็นว่ามีการส่งค่า Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= ไปกับ header ซึ่งค่า  dXNlcm5hbWU6cGFzc3dvcmQ= ได้มาจาก base64_encode('username:password'); ซึ่งเป็นการเข้ารหัสแบบ base64 นั่นเอง

มีอีกวิธีหนึ่งที่เราพบเห็นได้บ่อยๆ คือการส่งค่า Authorization แบบ Bearer (เช่น Line) ซึ่งโดยปกติแล้ว PHP จะไม่สามารถรับค่า Authorization แบบ Bearer ได้โดยตรง เพื่อความปลอดภัย แต่เราสามารถกำหนดค่าที่ .htaccess เพื่อรีไดเร็คค่านี้ไปยัง PHP ได้
RewriteEngine On
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]

หลังจากนี้ถ้ามีค่า Authorization ส่งมาจะถูกรีไดเร็คส่งไปยังตัวแปร $_SERVER ซึ่งเราสามารถรับค่า Authorization ที่ส่งมา ได้ที่ตัวแปร $_SERVER['HTTP_AUTHORIZATION'] บน PHP และนำไปตรวจสอบความถูกต้องในขั้นตอนต่อไป
ตัวอย่างทำการส่งค่า Authorization: Bearer 080042cad6356ad5dc0a720c18b53b8e53d4c274 (ด้วยวิธีเดิม) ซึ่งหลังจากที่เราเพิ่มการรีไดเร็ค header ที่ .htaccess แล้วเราจะสามารถรับค่าได้ที่ตัวแปร $_SERVER['HTTP_AUTHORIZATION'] บน PHP
$token = $_SERVER['HTTP_AUTHORIZATION']; // Bearer 080042cad6356ad5dc0a720c18b53b8e53d4c274

เราสามารถนำค่า $token ที่ได้รับไปตรวจสอบความถูกต้องได้

การรับค่า Authorization ของ PHP ยังมีอีกวิธีที่สามารถรับได้ ถ้า Server รองรับ คือการรับค่าด้วยฟังก์ชั่น apache_request_headers() ดังตัวอย่าง
if (function_exists("apache_request_headers")) {
    $headers = apache_request_headers();
    $token = isset($headers['Authorization']) ? $headers['Authorization'] : '';
}

ตัวแปร $headers จะรับค่า header ของ PHP ทั้งหมดที่สามารถอ่านได้ส่งกลับมาเป็นแอเรย์ ซึ่งถ้ามีค่า Authorization ส่งมาด้วยก็จะอยู่ที่ตัวแปร $headers['Authorization'] (สำหรับค่าอื่นๆ ที่ส่งมาด้วยสามารถ print_r($headers) ออกมาดูได้)

ในกรณีที่ต้องการเรียก API จากโดเมนอื่น จะต้องกำหนดค่า ที่ .htaccess เพิ่มเติมด้วย เพื่อให้สามารถรับค่า Authorization จากโดเมนอื่นได้
# Cross domain access for API
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, Authorization, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"


สามารถดูตัวอย่างการนำไปใช้แบบเต็มๆได้ที่ ตัวอย่างการใช้งาน API ด้วย Kotchasan
ผู้เขียน goragod โพสต์เมื่อ 12 พ.ย. 2563 เปิดดู 11,296 ป้ายกำกับ .htaccessApachePHP
^