GETとPOSTは「データの送り方の違い」として説明されることが多いですが、実務ではそれ以上に設計とセキュリティに直結する重要な判断ポイントです。
特に問題になるのは、「POSTの方が安全」「GETは使わない方がいい」といった誤解です。この認識のまま開発すると、普通に事故が起きます。
通信の前提を理解するなら、 DNSの役割とドメイン設定 もあわせて確認すると全体像がつながります。
まず最も重要な前提です。
GETとPOSTの違いは「安全かどうか」ではありません。
どちらもHTTPなら盗聴されますし、HTTPSならどちらも暗号化されます。
つまり安全性は次の1点で決まります。
HTTPSを使っているかどうか
この前提を外したまま「POSTだから安心」と思っていると、ログイン情報や個人情報が普通に漏れます。
GETの最大の特徴は「URLにすべて出ること」です。これがそのままリスクになります。
例えば以下のようなリクエストです。
/login?email=test@example.com&password=123456
この設計は一見動きますが、実務では完全にアウトです。
理由はシンプルで、情報があらゆる場所に残るからです。
つまり、GETに機密情報を載せると「漏れる前提の設計」になります。
さらに問題なのが、GETはリンクを踏むだけで実行される点です。
以下のようなコードがあると、ユーザーは気づかないうちに処理を実行させられます。
<img src="https://example.com/delete?id=123">
これはCSRFの典型パターンで、「見ただけで削除される」状態になります。
POSTは「URLに出ない」ため安全そうに見えますが、それは錯覚です。
実際には次のような問題があります。
開発者ツールを開けば、POSTの内容は普通に確認できます。HTTP通信であれば盗聴も可能です。
つまり、POSTは「隠れているだけ」であり、セキュリティとは無関係です。
POSTでも外部サイトから自動送信すれば、不正リクエストは成立します。
つまり、POSTだから安全という考えは完全に誤りです。
POSTは再送信が可能なため、決済や登録で「二重処理」が発生します。
実際の現場では「決済が2回通った」「注文が重複した」といった事故は珍しくありません。
ここまでの説明を、実際に手を動かして確かめてみましょう。以下のデモは演出ではありません。本当にこのサーバーへ情報を送り、新しいタブに結果ページを表示します。この記事のページ自体は何も変化しないので、安心して何度でも試してください。
下の欄に何か入力し、GET・POSTそれぞれのボタンで送信してみてください。演出ではなく、実際に新しいタブでこのサーバーに情報が送られ、届いた内容がそのまま表示されます。
開いた別ページの①のURLを見比べてみてください。GETで送った場合はURLにgp_msg=…が入り、POSTで送った場合は入りません。これは説明用の演出ではなく、実際のブラウザの挙動です。
開いた結果ページの「①このページの実際のURL」を見比べてみてください。GETで送った場合はURLの末尾に?gp_msg=…という形で入力内容がそのまま入りますが、POSTで送った場合はURLに一切残りません。これが「GETはURLに入るが、POSTは入らない」という違いの実物です。
POST版の結果ページを開いたまま再読み込みしてみると、ブラウザから「フォームを再送信しますか?」と確認が出ることもあります。これは、POSTで送った情報がそのページのURLにも、ブラウザの中にも保存されていないために起きる現象です。GETのようにURLをブックマークしたり人に共有したりするだけでは、POSTで送った情報は再現できません。これが「POSTは情報を送れるが、保持できない」という性質です。
かなり典型的な失敗例です。
本来POSTで実装すべき削除処理を、GETで作ってしまったケースです。
/admin/user/delete?id=125
この設計の何が危険かというと、「URLにアクセスしただけで削除される」点です。
その結果、以下のような事故が起きます。
つまり、GETで状態変更をすると「誰でもいつでも実行できる操作」になります。
ここまで見てきたルールはシンプルです。データを読むだけならGET、データを変更するならPOST。以下のデモで、実際にボタンを連打して確かめてみてください。
「データを読むだけ→GET」「データを変更する→POST」を、実際に何度も押して確かめてください。
GETボタンは何度押しても件数が変わりません。POSTボタンを押すと1件増えます。実際に連打して確かめてみてください。
GETボタンはどれだけ押しても件数が変わらず、POSTボタンを押した回数だけ件数が増えたはずです。GETは「読み込むだけ」なので、ブラウザが何度リクエストを送っても、ページを再読み込みしても、何も変化しません。これがGETの正しい姿です。
もしこの「いいねする」処理を、間違えてGETで作ってしまったらどうなるでしょうか。前述の/admin/user/delete?id=125と同じ理屈で、リンクを踏んだだけ、クローラーが巡回しただけ、ブラウザが先読みしただけで、件数が勝手に増減してしまいます。GETは「何度実行されても安全」であることが前提のため、ブラウザや検索エンジンのクローラーは確認なしにGETリクエストを送ってきます。だからこそ、データを変更する処理は必ずPOSTで作る必要があるのです。
実務ではシンプルに以下で判断します。
これだけです。
さらにセキュリティ観点では次のルールが重要です。
このルールを守るだけで、ほとんどの事故は防げます。
GETとPOSTの違いは単なる仕様ではなく、設計ミスがそのまま事故につながる領域です。
特に重要なのは次の2点です。
GETは「見られてもいいもの」
POSTは「変更するもの」
そしてどちらにも共通して必要なのが、HTTPSとCSRF対策です。
ここを外さなければ、Webアプリの基本的なセキュリティは大きく崩れません。