Python base64.urlsafe_b64encode: ส่งไบต์ใน URL โดยไม่พังเครื่องหมาย
น้องกายEngineering
Base64 ปกติใช้ + กับ / ซึ่งใน URL ต้อง escape ยุ่ง base64.urlsafe_b64encode เปลี่ยนเป็น - กับ _ เหมาะกับโทเคนในลิงก์หรือชื่อไฟล์ครับ
WHY: ตัวอักษรที่ลิงก์กลืนได้
เหมือนเขียนป้ายติดพัสดุด้วยปากกาที่น้ำไม่ละลาย — ถ้าใช้ปากกาน้ำฝน ป้ายเลอะตอนโดน query string
import base64
import unittest
def to_url_token(data: bytes) -> str:
return base64.urlsafe_b64encode(data).decode("ascii").rstrip("=")
def from_url_token(token: str) -> bytes:
pad = "=" * (-len(token) % 4)
return base64.urlsafe_b64decode(token + pad)
class UrlsafeTests(unittest.TestCase):
def test_roundtrip(self) -> None:
raw = b"showkhun-lab:\xff\x00"
token = to_url_token(raw)
self.assertNotIn("+", token)
self.assertNotIn("/", token)
self.assertEqual(from_url_token(token), raw)
def test_empty(self) -> None:
self.assertEqual(from_url_token(to_url_token(b"")), b"")
if __name__ == "__main__":
unittest.main()
HOW: ถอด padding ตอนส่ง เติมตอนรับ
หลายระบบตัด = ทิ้งใน URL ฝั่งรับจึงต้องเติม padding ให้ความยาวหาร 4 ลงตัวก่อน urlsafe_b64decode ใช้คู่ encode/decode แบบ urlsafe ให้ตรงกันทั้งสองฝั่ง อย่าผสมกับ b64encode มาตรฐาน
GOTCHA: นี่ไม่ใช่การเข้ารหัสลับ
Base64 เป็นแค่การเข้ารหัสรูปแทน (encoding) ใครอ่านโทเคนได้ก็ถอดไบต์ได้ ถ้าต้องการความลับต้องใช้ cryptography แยกต่างหาก
Recap
- ใช้ urlsafe เมื่อฝังใน URL / ชื่อไฟล์
- จัดการ padding ให้ครบตอนถอด
- อย่าสับสน encoding กับ encryption