Base64URL は 2 つのアルファベット文字を変更します。標準の Base64 のプラスはダッシュになり、スラッシュはアンダースコアになります。エンコードされた情報は変更されません。このバリアントは、周囲のプロトコルがプラスまたはスラッシュに特別な意味を与える場合に役立ちますが、すべての URL またはアプリケーション ルールから値を免除するわけではありません。
違いを明らかにするベクトルを使用する
バイト列 FB FF のエンコード結果は、標準の Base64 では +/8= 、Base64URL では -_8= です。Hello のようなテスト入力では両方式に共通する文字しか出力されないため、URL セーフな変換が正しく動いているかどうかを確認できません。
const standard = btoa(String.fromCharCode(251, 255));
const urlSafe = standard.replace(/\+/g, '-').replace(/\//g, '_');
console.log(standard); // +/8=
console.log(urlSafe); // -_8=
パディングは別の契約です
多くのトークン形式では末尾の等号(=)を省略しますが、保持するシステムもあります。文字集合の変更とパディングの省略は、別々に決める事項です。パディングのない入力の文字数を 4 で割った余りが 2 なら、パディング付きの表現には等号を 2 個追加します。余りが 3 なら、等号は 1 個必要です。余りが 1 の入力は、パディングの追加だけでは修復できません。1 文字が表す 6 ビットだけでは、1 バイトを完全に表せないためです。
検証するときは、最後の文字の未使用ビットもチェックします。それらを無視するデコーダは、同じバイト シーケンスに対して複数の文字列を受け入れる可能性があります。このあいまいさは、アプリケーションがデコードされたバイトではなくエンコードされた文字列を比較する場合に問題になる可能性があります。正規プロデューサーは、合意された表現を 1 つ出力する必要があります。
クエリ解析と Base64 デコードを混同しないでください
フォーム スタイルのクエリ解析では、リテラルのプラスはスペースとして解釈されます。したがって、エスケープせずにクエリに貼り付けられた標準の Base64 値は、デコーダが認識する前に破損する可能性があります。次のようにクエリを構築します URLSearchParamsまたは、受信プロトコルで指定されている場合は Base64URL バリアントを使用します。
const query = new URLSearchParams({ payload: '+/8=' });
console.log(query.toString()); // payload=%2B%2F8%3D
console.log(query.get('payload')); // +/8=
すべてのスペースを自動的にプラスに置き換えないでください。スペースは本物の書式設定であるか、別のエラーの証拠である可能性があります。ソースを保存し、それを変更したトランスポート層を特定し、意図的な修正を適用します。 JWT セグメントの場合は、一般的な修復ポリシーを作成するのではなく、トークン形式の Base64URL ルールを使用します。
標準アルファベットと URL セーフ アルファベットについては、次のとおりです。 RFC 4648。統合では、パディング、空白の受け入れ、最大長については明示的な選択が必要です。