AIStacker
Webベストプラクティスガイド8 分で読めます

redirect_uri と Query Params での encodeURI と encodeURIComponent の使い分け

redirect_uri、ネストされた URL、query value をどの境界でエンコードすべきかを実例ベースで整理したガイドです。

このガイドで扱う内容
3
このガイドで使用するツール
3
関連トピック
6
ガイド概要

URL エンコードの不具合は、関数選択そのものよりも、どの境界をエンコードしたかで起こることが多いです。encodeURIencodeURIComponent かを急いで選んでも、対象が URL 全体なのか、別の URL に入る 1 つの値なのかが曖昧なままだと、1 つのケースだけ直って別のケースが壊れます。

大事なのは「どちらが優れているか」ではなく、「今エンコードしているのは何か」を明確にすることです。ブラウザがそのまま読む最終 URL なのか、別の query string の中に入る 1 つの値なのか。この境界が明確になれば、選ぶべきエンコード方法も安定します。

01

URL 全体とネストされた値は別の面として扱う

#

もし対象がブラウザにそのまま読ませる最終 URL なら、encodeURI 的な挙動の方が自然です。/?&= のような区切り文字を読みやすいまま残せるからです。

一方で、その文字列が別の URL の中に 1 つの値として入るなら話は変わります。ネストされた redirect_uri は、外側の query string に分解されないよう、通常は 1 つの component としてエンコードする必要があります。

Note

本番で多い失敗は、ネストされた URL を最終 URL と同じ扱いでエンコードしてしまうことです。

どちらの境界で扱うべきか迷うときは、URL Encoder で両方の結果を並べて確認すると判断しやすくなります。

このセクションで使うツール

02

1 つの値として保ちたいものは component としてエンコードする

#

スペース、&=、あるいは別の URL を含む query value は、通常は外側の URL に入れる前に 1 つの component としてエンコードする方が安全です。そうしないと、外側の parser が途中で分割してしまい、一部を別キーとして誤解することがあります。

Read Only
Wrong:
/login?redirect_uri=https://app.example.com/callback?from=pricing&utm=ads

Safer:
/login?redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback%3Ffrom%3Dpricing%26utm%3Dads

見た目は読みにくくなりますが、ネストされた target が 1 つの単位として保たれるため、安全性は高くなります。ここでは encodeURIComponent 的な挙動の方が適しています。

このセクションで使うツール

03

さらにエンコードする前に、二重エンコードの兆候を確認する

#

すでに %3A%2F%25 のような並びが見えているなら、もう一度エンコードすると問題を隠してしまうことがあります。特にリダイレクト不具合では、別レイヤーで同じ値を二重に処理してしまうケースがよくあります。

安全な進め方は次の通りです。

  • まず現在の入力をそのまま確認する
  • 対象が URL 全体か 1 つの component かを決める
  • その境界で 1 回だけエンコードする
  • デバッグ時だけ 1 回デコードして中身を確認する

どのレイヤーがエンコード責任を持つか説明できない場合は、もう 1 回処理を加える前に設計を見直した方が安全です。

このセクションで使うツール