application/x-www-form-urlencodedって何?
ローカルサーバーを使ってLINEログインの基礎を理解するの記事を書いた時にapplication/x-www-form-urlencodedがわからず、気になったので、忘備録にChatGPTとのやりとりを残す。(※内容の精査はしてないので、あくまで参考程度に)
Aさん:
application/x-www-form-urlencodedって何?
Bさん:
いい質問だね!簡単に言うと、application/x-www-form-urlencoded は、フォームのデータを送るときのフォーマットの一つなんだ。Webフォームでよく使われる方式だね。
Aさん:
フォームのデータって、例えばログインフォームの「メールアドレス」と「パスワード」とかですか?
Bさん:
そうそう!例えば、以下のようなHTMLのログインフォームがあるとするね。
<form action="/login" method="POST">
<input type="text" name="email" value="test@example.com">
<input type="password" name="password" value="123456">
<button type="submit">ログイン</button>
</form>
このフォームのデータがサーバーに送信されるとき、application/x-www-form-urlencoded 形式でエンコードされるんだ。
Aさん:
エンコードって何ですか?😵
Bさん:
データを特定の形式に変換することだね。この場合、フォームのデータが URLのクエリパラメータのような形 になる。
例えば、上のフォームを送信すると、サーバーにはこういうデータが送られてくるんだ。
email=test%40example.com&password=123456
test@example.com
の @
が %40
に変換されているのが分かる?これがエンコードだよ。
Aさん:
なるほど!URLのクエリパラメータみたいな形式になるんですね。
じゃあ、express.urlencoded({ extended: true })
は何をしてるんですか?
Bさん:
これは Express が application/x-www-form-urlencoded 形式のデータを解析(パース)して req.body に入れてくれる 便利なミドルウェアなんだ。
例えば、さっきのフォームデータを POST で送信すると、Express のルートでこうやって受け取れるよ。
app.post('/login', (req, res) => {
console.log(req.body); // { email: 'test@example.com', password: '123456' }
res.send('ログイン成功');
});
Aさん:
おお、req.body に { email: 'test@example.com', password: '123456' }
みたいにオブジェクトで入るんですね!便利✨
Bさん:
そうなんだよ!ちなみに extended: true
のオプションをつけると、ネストしたオブジェクト(例えば user[name]=Alice
みたいなデータ)もちゃんと扱えるようになる。
Aさん:
なるほど!
じゃあ、application/json
とはどう違うんですか?
Bさん:
いい質問だね!application/json
の場合、送信されるデータは JSON形式 になる。
例えば、同じデータを application/json
で送るとこうなる:
{
"email": "test@example.com",
"password": "123456"
}
そして、Express 側では app.use(express.json());
を使えば req.body
にオブジェクトとして格納される。
Aさん:
つまり、application/x-www-form-urlencoded
は「フォーム送信でよく使う形式」で、データが URLのクエリパラメータっぽい形になって、application/json
は JSONの形のまま送るってことですね?
Bさん:
そのとおり!express.urlencoded()
は application/x-www-form-urlencoded
をパースするためのもの、express.json()
は application/json
をパースするためのもの、って覚えておくといいよ。
Aさん:
めっちゃ分かりやすかったです!ありがとうございます!😆
Bさん:
どういたしまして!実際に試しながら学ぶともっと理解が深まるよ👍
You said:
今回はログインフォームからLINEログインボタンをクリックしてLINEログインでリダイレクトしてサーバーにアクセスするだけなので、フォームからデータを送信してないように思えるのですが、なぜapplication/x-www-form-urlencoded
が必要でしょうか?
ChatGPT said:
Aさん:
Bさん、LINEログインではログインフォームからLINEのログインページにリダイレクトするだけですよね?フォームのデータを送っているわけじゃないのに、なぜ application/x-www-form-urlencoded
の設定が必要なんですか?
Bさん:
いいところに気づいたね!確かに、フロントエンドのログインフォームからサーバーに直接データを送るわけではないけど、サーバーがLINEの認証サーバーとやりとりするときに application/x-www-form-urlencoded
を使う場面があるんだ。
LINEログインの流れ
- ユーザーがLINEログインボタンをクリック
- ブラウザが https://access.line.me/oauth2/v2.1/authorize?... にリダイレクトされる。ここでは application/x-www-form-urlencoded は関係ない。
- LINEの認証が完了すると、LINEから指定したリダイレクトURL (redirect_uri) に戻る。
- 例: https://your-server.com/callback?code=abcd1234&state=xyz
- ここでも application/x-www-form-urlencoded は関係ない。
- サーバーがLINEのトークンエンドポイントにリクエストを送る
- https://api.line.me/oauth2/v2.1/token に対して POSTリクエストを送信
- ここで application/x-www-form-urlencoded のフォーマットを使う!
LINEのトークンリクエストが application/x-www-form-urlencoded を使う理由
LINEのAPIドキュメントによると、access_token を取得するためのリクエストは以下のような POST リクエストを送る必要がある。
リクエストの例
POST https://api.line.me/oauth2/v2.1/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=abcd1234
&redirect_uri=https%3A%2F%2Fyour-server.com%2Fcallback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
サーバーはこの URLエンコードされたデータを送るため、express.urlencoded({ extended: true })
の設定が必要になるんだ。
Aさん:
なるほど!application/x-www-form-urlencoded
を使うのは、LINEのサーバーに access_token
を取得するリクエストを送るときなんですね!
Bさん:
その通り!だから、ログインフォームからのデータを直接送らなくても express.urlencoded({ extended: true })
の設定が必要になるんだよ。
Aさん:
めっちゃスッキリしました!ありがとうございます!
Discussion