นากกายเปลี่ยนพัสดุเป็นป้ายที่ติดลิงก์ได้โดยไม่มีเครื่องหมายอันตราย

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