Применение · Разработчикам

OpenBadges для разработчиков

Три типа JSON-документов, цепочка из трёх HTTP-запросов, рабочий код для проверки и отличия версий 2.0 и 3.0. Здесь техническая модель — без воды и без маркетинга.

С точки зрения разработчика OpenBadges — это набор JSON-LD-документов, выложенных на стороне эмитента по обычным HTTP-URL. Никакого центрального сервера, никакого SDK, который надо лицензировать — только публично описанная модель данных и три типа документов, связанных ссылками.

В версии 2.0 проверка устроена как «дочитать цепочку JSON и сверить поля». В версии 3.0 формат переоформлен под Verifiable Credentials консорциума W3C: assertion становится подписанным credential, и проверка не требует обращения к эмитенту вовсе.

Объекты модели данных

Четыре сущности, которые описывает спецификация. Их связь — это и есть «бейдж».

Issuer / Profile
Кто выдаёт. Объект с id (URL), name, url и контактом. Точка доверия всей цепочки — клиент смотрит, что профиль реально размещён по этому адресу.
Achievement / BadgeClass
Что выдаётся. Шаблон достижения: name, description, criteria, image, теги навыков и согласования (alignment). Один BadgeClass — много assertion.
Assertion / Credential
Факт выдачи конкретному получателю. Ссылается на BadgeClass и эмитента, содержит recipient, issuedOn, evidence и блок verification.
Verification
Способ проверки. 2.0 — hosted (JSON по URL) или signed (JWS). 3.0 — криптографический proof по модели VC Data Model.

Полный цикл выдачи и проверки

Что происходит на каждом шаге, и почему ничего нельзя подделать незаметно.

  1. Эмитент описывает себя

    Публикует Profile-документ по постоянному URL — например, https://issuer.example/profile.json. Это «удостоверение» организации.

  2. Эмитент описывает достижение

    Публикует BadgeClass: за что бейдж выдаётся, критерии, картинка. Ссылка на Profile внутри.

  3. Эмитент выдаёт бейдж конкретному человеку

    Создаёт Assertion (факт выдачи) с указанием BadgeClass, получателя и даты. Получает URL вида https://issuer.example/assertions/42.

  4. Получатель показывает ссылку

    Кладёт ссылку в резюме, профиль, бэкпак. Никакой пересылки бейджа — только URL.

  5. Проверяющий читает цепочку

    GET assertion → читает badge → GET BadgeClass → читает issuer → GET Profile. Три HTTP-запроса, всё. Подлинность подтверждается тем, что данные сходятся.

Три JSON-документа

Минимальные примеры всех трёх. Этого достаточно, чтобы прочитать любой реальный бейдж 2.0.

Profile — кто выдаёт

{
  "@context": "https://w3id.org/openbadges/v2",
  "type": "Profile",
  "id": "https://issuer.example/profile.json",
  "name": "Учебный центр «Пример»",
  "url": "https://issuer.example",
  "email": "registry@issuer.example"
}
Документ-удостоверение организации. Лежит по постоянному URL.

BadgeClass — что выдаётся

{
  "@context": "https://w3id.org/openbadges/v2",
  "type": "BadgeClass",
  "id": "https://issuer.example/badges/python-basics",
  "name": "Основы Python",
  "description": "Освоен синтаксис Python и решены 20 учебных задач.",
  "image": "https://issuer.example/badges/python-basics.png",
  "criteria": "https://issuer.example/criteria/python-basics",
  "issuer": "https://issuer.example/profile.json"
}
Шаблон достижения. Один BadgeClass — много assertion.

Assertion — факт выдачи

{
  "@context": "https://w3id.org/openbadges/v2",
  "type": "Assertion",
  "id": "https://issuer.example/assertions/42",
  "recipient": {
    "type": "email",
    "hashed": true,
    "salt": "abc123",
    "identity": "sha256$a1b2c3d4e5f6..."
  },
  "badge": "https://issuer.example/badges/python-basics",
  "issuedOn": "2026-03-14T10:00:00Z",
  "verification": { "type": "HostedBadge" },
  "evidence": "https://issuer.example/evidence/42"
}
Конкретный бейдж, выданный конкретному человеку. recipient захеширован, проверка — HostedBadge.

Как прочитать бейдж из кода

Полный пример: assertion → BadgeClass → Profile. Три fetch, ноль зависимостей.

// Прочитать hosted-бейдж 2.0: assertion → BadgeClass → Profile
const assertionUrl = 'https://issuer.example/assertions/42';
const assertion = await fetch(assertionUrl).then((r) => r.json());

// 1. Достаём BadgeClass — что именно подтверждается
const badgeRef = typeof assertion.badge === 'string' ? assertion.badge : assertion.badge.id;
const badge = await fetch(badgeRef).then((r) => r.json());

// 2. Достаём Profile эмитента — кто выдал
const issuerRef = typeof badge.issuer === 'string' ? badge.issuer : badge.issuer.id;
const issuer = await fetch(issuerRef).then((r) => r.json());

// Теперь видим всё: кто, что, когда, по каким критериям
console.log({
  achievement: badge.name,
  issuer: issuer.name,
  issuedOn: assertion.issuedOn,
  verification: assertion.verification?.type,
  evidence: assertion.evidence,
});
Базовая «сборка цепочки». В продакшене добавьте проверку revocation, схемы и таймауты.

Версия 3.0 — Verifiable Credentials

Тот же бейдж как W3C-credential. Подпись внутри, проверка — без обращения к эмитенту.

{
  "@context": [
    "https://www.w3.org/ns/credentials/v2",
    "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json"
  ],
  "id": "https://issuer.example/credentials/42",
  "type": ["VerifiableCredential", "OpenBadgeCredential"],
  "issuer": {
    "id": "did:web:issuer.example",
    "type": "Profile",
    "name": "Учебный центр «Пример»"
  },
  "validFrom": "2026-03-14T10:00:00Z",
  "credentialSubject": {
    "id": "did:example:recipient",
    "type": "AchievementSubject",
    "achievement": {
      "id": "https://issuer.example/achievements/python-basics",
      "type": "Achievement",
      "name": "Основы Python",
      "criteria": { "narrative": "Освоен синтаксис и решены задачи." }
    }
  },
  "proof": {
    "type": "DataIntegrityProof",
    "cryptosuite": "eddsa-rdfc-2022",
    "proofPurpose": "assertionMethod",
    "verificationMethod": "did:web:issuer.example#key-1",
    "proofValue": "z58DAdFfa9SkqZMVPxAQpic..."
  }
}
OpenBadgeCredential 3.0 c DataIntegrityProof. Получатель — DID, не e-mail.

Как устроена проверка

  • Hosted (2.0) — клиент GET-ит assertion по URL и сверяет данные с публичным Profile эмитента. Подделать assertion нельзя: ссылка ведёт на сервер эмитента, и подменить ответ может только тот, кто им владеет.
  • Signed (2.0) — бейдж представлен как JWS (JSON Web Signature) с подписью эмитента. Проверяется его публичным ключом, опубликованным в Profile. Сам JWS можно носить с собой — серверу эмитента он не нужен.
  • Verifiable Credentials (3.0) — проверка криптографического proof по модели W3C VC. Подпись считается через ed25519/EcDSA, верификация — полностью офлайн. Это решает кейс «эмитент закрылся, а бейдж должен оставаться проверяемым».
  • Revocation — отозванные бейджи помечаются: в 2.0 — через revocationList по ссылке из Profile, в 3.0 — через StatusList2021 или аналог. Перед тем как доверять бейджу, проверьте статус.

Приватность получателя

Что хешируется, а что попадает в публичный JSON.

  • Идентификатор получателя обычно хеширован — указано hashed: true плюс salt. Это позволяет получателю доказать владение, но защищает от утечки e-mail при публикации бейджа.
  • В 3.0 получатель чаще представлен как did:example:... — децентрализованный идентификатор, не привязанный к серверу.
  • Поле evidence может вести на публичные материалы — решает эмитент. Не публикуйте туда персональные данные без согласия.

Точки интеграции

  • LMS / EdTech — выдача бейджа по завершении курса через вебхук или платформенный API. Бейдж публикуется на хосте LMS и сразу проверяем по ссылке.
  • HRM / ATS — импорт подтверждённых навыков кандидата и сотрудников. Открытый стандарт позволяет принимать бейджи из любого совместимого источника.
  • Бэкпаки и кошельки — экспорт/импорт по стандарту для переносимости (OpenBadges Backpack, Badgr, Credly).
  • Подписи и резюме — встраивание ссылки или баджа-картинки с запечённым assertion (PNG iTXt / SVG metadata).

Частые вопросы

С какой версии стандарта начать?
Если нужна максимальная совместимость с уже существующими валидаторами (Credly, Badgr, агрегаторы) — стартуйте с 2.0. Если важна криптографическая проверяемость, офлайн-валидация и независимость от хоста эмитента — закладывайте 3.0 на базе Verifiable Credentials. На практике многие платформы поддерживают обе версии параллельно.
Как скрывается e-mail получателя?
Идентификатор получателя обычно хешируется (sha256 с солью), а в assertion указывается hashed: true. Это позволяет владельцу e-mail доказать, что бейдж выдан именно ему — сосчитав хеш и сравнив с identity, — но прочитать сам адрес из assertion нельзя. В 3.0 чаще используется DID получателя без обращения к e-mail.
Что хранится у эмитента, а что — у получателя?
В 2.0 эмитент хранит ВСЕ три JSON: Profile, BadgeClass, Assertion. У получателя только ссылка. В 3.0 модель меняется: эмитент создаёт подписанный credential, отдаёт его получателю, и дальше получатель сам распоряжается им (хранит в кошельке, отдаёт работодателю). Эмитеру не нужно ничего хранить.
Можно ли «запечь» бейдж в картинку?
Да. В PNG данные кладутся в iTXt/tEXt chunk с keyword "openbadges" — либо URL assertion, либо весь JSON inline. В SVG — внутри <openbadges:assertion>. Это удобно для офлайн-обмена: пользователь скачивает картинку, валидатор извлекает JSON и проверяет.
Где взять официальную спецификацию?
Спецификации публикует 1EdTech: «OpenBadges v2.0» (imsglobal.org/sites/default/files/Badges/OBv2p0Final/) и «OpenBadges v3.0» (imsglobal.org/spec/ob/v3p0/). Версия 3.0 опирается на «Verifiable Credentials Data Model 2.0» от W3C. Все три ссылки собраны в разделе «Документация и API».
Что делать, если эмитент закрылся?
Для 2.0 (hosted) — assertion перестанет проверяться, потому что URL умрёт. Для 2.0 (signed) и для 3.0 — подпись остаётся валидной без эмитента: проверка идёт по криптографии, не по HTTP. Это одна из главных причин переезда стандарта на VC в 3.0.

Документация и живая проверка