🔐
← Назад к руководствам

URL-безопасное кодирование Base64: что это и почему это важно

· Теги: base64, url-safe, base64url, jwt, encoding, web-development, api

Что такое URL-безопасное кодирование Base64?

URL-безопасное кодирование Base64 (также называемое Base64url) — это вариант стандартного Base64, который заменяет символы, имеющие специальное значение в URL и именах файлов, на безопасные альтернативы. Стандартный Base64 использует + и / в составе своего 64-символьного алфавита, а также = для дополнения, и все три проблематичны в URL, строках запросов и путях к файлам.

Base64url решает эту проблему двумя простыми заменами:

| Стандартный Base64 | URL-безопасный Base64 | |-----------------|-----------------| | + (плюс) | - (минус) | | / (слеш) | _ (подчёркивание) | | = (дополнение) | опускается (обычно) |

Почему стандартный Base64 ломает URL

Когда строка в формате Base64, содержащая + или /, появляется в URL, поведение браузера и сервера становится непредсказуемым.

Проблема с +

В строках запросов URL символ + интерпретируется как пробел. Это поведение происходит из спецификации application/x-www-form-urlencoded и приводит к тому, что декодированные данные содержат неожиданные пробелы.

Например, строка Base64 вида Pj4+Pz8/Pw== содержит символы +. Если она появляется в параметре URL ?token=Pj4+Pz8/Pw==, сервер увидит ?token=Pj4 Pz8/Pw==+ превращается в пробел.

Проблема с /

В путях URL символ / является разделителем пути. Строка Base64 вида ab/CD+Ef== содержит /, который будет интерпретирован как уровень директории. Если она появляется в сегменте URL, и клиент, и сервер могут неправильно интерпретировать структуру.

Проблема с =

Символ = используется для пар ключ-значение в строках запросов. Завершающий = в ?data=SGVsbG8= может быть неоднозначным — является ли = частью дополнения Base64 или синтаксисом параметра запроса?

Хотя процентное кодирование может исправить эти проблемы (+ превращается в %2B, / — в %2F), оно увеличивает длину строки и усложняет отладку. Base64url — более чистое решение.

Как работает Base64url

Base64url формально определён в RFC 4648 Section 5. Он использует точно такой же алгоритм, как и стандартный Base64 — 3 байта превращаются в 4 символа — но с заменой одного символа на позициях 62 и 63 алфавита:

  • Индекс алфавита 62: +- (минус)
  • Индекс алфавита 63: /_ (подчёркивание)

Дополнение (=) обычно удаляется, поскольку его можно вывести из длины строки при декодировании. Строка Base64url всегда является допустимым компонентом URL без дополнительного экранирования.

До и после

Вот как одни и те же бинарные данные выглядят в обоих форматах:

Стандартный:  Pj4+Pz8/Pw==
URL-безопасный:  Pj4-Pz8_Pw

Где используется Base64url

JSON Web Tokens (JWT)

JWT — самый заметный пользователь Base64url. Каждый JWT состоит из трёх частей — заголовка, полезной нагрузки и подписи — каждая из которых закодирована в URL-безопасном Base64 и разделена точками:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNqP0m2iTgCjD0

Обратите внимание на дефисы и подчёркивания — никаких знаков плюса или слешей. Если бы JWT использовал стандартный Base64, токены ломались бы при передаче в качестве параметров URL, что является наиболее распространённым способом их использования в веб-приложениях.

OAuth и OpenID Connect

Как OAuth 2.0, так и OpenID Connect полагаются на JWT для токенов доступа и ID-токенов, что делает кодирование Base64url фундаментальным для современной аутентификации. Поток кода авторизации, неявный поток и поток клиентских учётных данных — все передают токены, использующие Base64url.

Веб-API и параметры запросов

Многие REST и GraphQL API принимают данные в формате Base64 в параметрах запросов для курсоров пагинации, фильтров или закодированных нагрузок. Base64url гарантирует, что эти параметры работают корректно без дополнительного URL-кодирования.

Реальный пример — курсорная пагинация API:

GET /api/users?cursor=MjAyNC0wMS0xNVQxMDozMDowMFo

API GitHub использует именно этот шаблон для пагинации больших наборов результатов.

Имена файлов и файловое хранилище

Строки Base64url образуют безопасные имена файлов, поскольку они не содержат разделителей пути (/), специальных символов, сбивающих с толку файловые системы, и символов, недопустимых в Windows (:, *, ? и т.д.).

Сети доставки контента и ключи кэша

CDN и слои кэширования часто используют значения в формате Base64url в качестве ключей кэша. Стандартный Base64 с / создавал бы ложные иерархии директорий в пространстве имён кэша, что приводило бы к неоднозначным ключам.

Преобразование между стандартным Base64 и Base64url

Преобразование между двумя вариантами просто реализуется на любом языке:

JavaScript

// Стандартный Base64 в URL-безопасный Base64
function base64ToBase64url(base64) {
  return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}

// URL-безопасный Base64 в стандартный Base64
function base64urlToBase64(base64url) {
  let result = base64url.replace(/-/g, '+').replace(/_/g, '/');
  // Восстановление дополнения
  while (result.length % 4) {
    result += '=';
  }
  return result;
}

Node.js

Node.js предоставляет нативную поддержку Base64url начиная с версии 15.7.0:

// Кодирование в Base64url
const encodedUrl = Buffer.from('Hello, world!').toString('base64url');
console.log(encodedUrl);
// Output: SGVsbG8sIHdvcmxkIQ

// Декодирование из Base64url
const decoded = Buffer.from(encodedUrl, 'base64url').toString('utf-8');
console.log(decoded);
// Output: Hello, world!

Python

import base64

# Кодирование в Base64url
encoded = base64.urlsafe_b64encode(b"Hello, world!")
print(encoded.decode())
# Output: SGVsbG8sIHdvcmxkIQ==

# Декодирование из Base64url
decoded = base64.urlsafe_b64decode(encoded)
print(decoded.decode())
# Output: Hello, world!

Когда использовать стандартный Base64, а когда Base64url

Используйте стандартный Base64 когда:

  • Кодируете вложения электронной почты (этого требует стандарт MIME)
  • Генерируете data URL для встраивания в HTML/CSS
  • Храните данные в базах данных, где безопасность URL не важна
  • Взаимодействуете с устаревшими системами, ожидающими стандартный Base64

Используйте Base64url когда:

  • Создаёте или разбираете JWT-токены
  • Передаёте закодированные данные в параметрах запросов URL или сегментах пути
  • Генерируете имена файлов из бинарных данных
  • Создаёте ключи кэша или идентификаторы
  • Работаете с OAuth-токенами или OpenID Connect

Попробуйте URL-безопасное кодирование Base64 онлайн

Используйте наш бесплатный онлайн кодировщик и декодировщик Base64 для преобразования между стандартным Base64 и URL-безопасным форматом Base64. Вставьте свои данные, выберите вариант и мгновенно получите результат.