Почему для оплаты используют POST, а не GET
Что проверяют
Знаете ли вы семантику методов HTTP и понимаете ли, что POST на самом деле даёт, а что нет. Вопрос любят именно потому, что дежурный ответ «POST безопаснее, данные не видно» неверен, и это слышно сразу.
Как отвечать
Главный аргумент семантический: GET по спецификации безопасный метод, он не должен менять состояние. Из этого вытекает поведение всей инфраструктуры вокруг:
- браузеры, прокси и краулеры свободно повторяют GET, предзагружают ссылки и кэшируют ответ. Списание по ссылке произойдёт от простого обхода роботом;
- параметры GET попадают в строку адреса, историю, закладки, логи веб-сервера и обратного прокси, а также в заголовок
Refererпри переходе; - кнопка «назад» и восстановление вкладки переигрывают GET молча, без вопроса пользователю.
Шифрование к делу не относится: под TLS зашифрован весь запрос вместе с адресом.
Дальше добавьте то, что отличает сильный ответ: POST не идемпотентен, поэтому платёж защищают ключом идемпотентности. Клиент генерирует ключ сам, сервер хранит связку ключа и результата и на повтор возвращает прежний ответ вместо второго списания.
@router.post("/payments")
async def create_payment(body: PaymentIn, idempotency_key: str = Header(...)):
if cached := await repo.get_by_key(idempotency_key):
return cachedИ отдельно: реквизиты карты через свой бэкенд обычно не проходят вовсе, их принимает платёжный шлюз, а сервису достаётся токен.
Где спотыкаются
Говорят, что POST шифрует данные. Он не шифрует ничего: меняется лишь то, где данные оседают по дороге. Без TLS тело POST читается так же свободно, как адрес.
Второе: утверждают, что GET неидемпотентен, а POST идемпотентен, либо путают идемпотентность с безопасностью метода. Идемпотентны GET, PUT и DELETE, POST нет, и как раз поэтому платежу нужен ключ идемпотентности, а не «защита самим методом».
Третье: упирают на ограничение длины адреса. Лимит существует, но для платежа он не главный: даже если данные влезут в строку запроса, проблема останется в повторах, логах и кэшировании, а не в числе символов.