Applogin Dashboard

Applogin — единая авторизация

Подключите вход через Google и email/пароль к своему приложению одним скриптом. Вся авторизация — вход, регистрация, подтверждение почты, сброс пароля, Google — происходит внутри защищённого iframe на applogin.one. Ваша страница никогда не видит пароль пользователя и ничего не проверяет — вы получаете только готовый app-scoped токен.

Что делает за вас платформа
  • Рисует форму входа/регистрации (в своём iframe) — вам не нужно её делать.
  • Принимает пароль, проверяет учётные данные, шлёт и проверяет коды с почты — вам не нужно ничего верифицировать.
  • Ведёт единый аккаунт пользователя (Google и пароль — один аккаунт).
  • Держит сквозную сессию и молча подхватывает вход между вашими приложениями.

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

Applogin — провайдер аутентификации (как Auth0/Clerk), но форма входа отдаётся во фрейме с нашего домена. Ваше приложение через SDK открывает этот фрейм (во всплывашке) и получает результат по postMessage. Токен — JWT, подписанный секретом вашего приложения (aud=app_id), поэтому он бесполезен в чужом приложении.

Ваше приложение (напр. emailwriter.online) │ applogin.js + applogin-ui.js (SDK/виджет) │ открывает всплывашку с iframe: ▼ ┌──────────────────────────────────────────┐ │ iframe → https://applogin.one/login │ ← пароль вводится ЗДЕСЬ │ (форма: Google / email+пароль / сброс) │ ваш JS его не видит └──────────────────────────────────────────┘ ▲ postMessage { token, user } (только вашему origin) │ ▼ Вы получаете app-токен → проверяете его на бэкенде (/v1/session/verify)
ПонятиеЧто это
Приложение (app)Сущность на платформе. Имеет публичный app_id, jwt_secret (проверка токена на бэкенде) и списки allowed_origins / redirect_uris.
End userГлобальный аккаунт (один на e-mail) для всех приложений платформы. Google и пароль линкуются к одному аккаунту.
App-токенJWT (HS256, aud=app_id), подписан jwt_secret вашего приложения. За ним — отзываемая сессия.
SSO-сессияГлобальная сессия в HttpOnly+Partitioned cookie al_sso на applogin.one. Общая в пределах одного top-level сайта.

Быстрый старт

Подключите два скрипта и смонтируйте виджет — он сам сделает тихий вход, покажет кнопку «Войти», откроет форму во фрейме и вернёт пользователя.

<script src="https://applogin.one/applogin.js?v=1"></script>
<script src="https://applogin.one/applogin-ui.js?v=1"></script>
<script>
  ApploginUI.mount({
    appId: "app_your_id",
    onAuth:   (user) => renderApp(user),  // signed in: { id, email, name, picture, email_verified }
    onLogout: ()     => showLanding()
  });
  // sign-out button:  ApploginUI.logout();
</script>

Всё. Форму, регистрацию, коды на почту, Google и сброс пароля берёт на себя Applogin. Единственное условие — зарегистрировать app_id и указать allowed_origins (см. Создание приложения).

Версия ?v=1 в URL скриптов нужна, чтобы браузер не отдавал старую закэшированную версию SDK при обновлениях.

Виджет ApploginUI рекомендуется

Готовый «замок» на приложение: пока не вошёл — показывает экран с кнопкой «Войти»; по клику открывает всплывашку с формой; после входа зовёт onAuth(user) и убирает экран.

МетодОписание
ApploginUI.mount({ appId, onAuth, onLogout, title? })Смонтировать. Делает тихий SSO; если не вошёл — рисует лендинг «Войти».
ApploginUI.logout()Выход (отзыв сессии + снова лендинг).
ApploginUI.getUser()Текущий пользователь или null.

Профиль (аватар, имя, e-mail) и кнопку «Выйти» рисуете вы из onAuth(user) — это ваш UI. Данные пользователя приходят готовыми.

Методы SDK (applogin.js) низкий уровень

Если нужен свой UX вместо виджета — работайте с SDK напрямую. Сначала Applogin.init({ appId }). Токен хранится в localStorage под ключом al_token_<appId>.

МетодОписаниеВозвращает
init({ appId })Инициализация.
getSession()Тихий SSO: подхватить сессию, если юзер вошёл в другом приложении того же сайта.{ authenticated, token, user }
openLogin()Открыть всплывашку с формой входа (iframe на applogin.one).{ token, user, lang } или null
verify()Проверить текущий токен.{ valid, user }
logout()Выход (отзыв сессии + очистка).
getToken()Текущий app-токен.string | null
Applogin.init({ appId: "app_xxx" });

// on load — silently try SSO:
const s = await Applogin.getSession();
if (s.authenticated) showApp(s.user);
else {
  const r = await Applogin.openLogin();     // modal with the applogin.one form
  if (r) showApp(r.user);
}
// attach Applogin.getToken() to your backend requests

Сквозной вход (SSO)

При входе Applogin ставит cookie al_sso с атрибутом Partitioned. Ключ партиции — top-level сайт (самый внешний). Поэтому:

const s = await Applogin.getSession();   // ← {authenticated:true,…} if a session exists in this partition
if (s.authenticated) showApp(s.user);
Требование allowed_origins. Фрейм входа проверяет всю цепочку предков (frame-ancestors), поэтому в allowed_origins приложения нужно перечислить и его собственный домен, и домен-обёртку (напр. appdock.pro).
Про изоляцию честно. Разделение «свой сайт → SSO, чужой top-level → заново» обеспечивает браузер (партиционирование cookie, CHIPS). В браузерах без CHIPS cookie может вести себя как общая — тогда автологин произойдёт и на отдельной странице приложения. Это не дыра: выдача токена всё равно гейтится по allowed_origins (чужой сайт токена не получит).

Языки

Hosted-форма входа говорит на 10 языках: English, Deutsch, Français, Español, Italiano, Português, 日本語, 한국어, 中文, Русский. По умолчанию она открывается на языке браузера пользователя (фоллбек — английский); язык можно сменить прямо в форме — меню с флагами внизу.

Под капотом URL формы принимает ?lang=xx (двухбуквенный код из списка выше) — SDK передаёт его за вас.

Живой пример: AppDock

appdock.pro — «док»-лаунчер: одна страница, которая открывает несколько приложений в iframe. Приложения живут на своих доменах:

ПриложениеДоменapp_id
Email Writeremailwriter.onlineapp_emailwriter
Audio Recorderaudiorecorder.infoapp_recorder

Войдите в Email Writer внутри дока, затем откройте Audio Recorder (тоже внутри дока) — вход подхватится сам: оба работают под одним top-level сайтом appdock.pro и делят одну SSO-партицию.

1. Док-лаунчер (appdock.pro)

<button class="tile" data-src="https://emailwriter.online/">Email Writer</button>
<button class="tile" data-src="https://audiorecorder.info/">Audio Recorder</button>
<iframe id="frame" allow="microphone; clipboard-write"></iframe>
<script>
  document.querySelectorAll(".tile").forEach(t =>
    t.onclick = () => document.getElementById("frame").src = t.dataset.src);
</script>

2. Приложение (напр. emailwriter.online)

<script src="https://applogin.one/applogin.js?v=1"></script>
<script src="https://applogin.one/applogin-ui.js?v=1"></script>
<script>
  ApploginUI.mount({
    appId: "app_emailwriter",
    title: "Email Writer — sign in",
    onAuth: (user) => {              // render the profile + the app
      header.textContent = user.name + " · " + user.email;
      app.hidden = false;
    },
    onLogout: () => { app.hidden = true; }
  });
</script>

3. Регистрация приложений для этого сценария

У каждого приложения в allowed_originsсвой домен + домен дока (frame-ancestors видит всю цепочку предков вложенного фрейма):

app_emailwriter → allowed_origins: ["https://emailwriter.online", "https://appdock.pro"]
app_recorder    → allowed_origins: ["https://audiorecorder.info", "https://appdock.pro"]
// redirect_uris (for Google): ["https://applogin.one/auth-callback.html"]
Итог поведения: внутри дока — единый вход между Email Writer и Audio Recorder; каждый по отдельности (свой домен как top-level) — вход заново. Приложения при этом не содержат формы входа — только ApploginUI.mount.

Проверка токена на вашем бэкенде

Фронт кладёт Applogin.getToken() в заголовок Authorization ваших запросов. На бэкенде токен проверяют двумя способами.

1. Ручкой платформы учитывает отзыв

POST https://applogin.one/api/v1/session/verify
{ "app_id": "app_xxx", "token": "<JWT from Authorization>" }
// → { "valid": true, "user": { "id": 2, "email": "…", "email_verified": true, "name": "…", "picture": null } }
//   invalid/revoked (logout) → { "valid": false, "user": null }

2. Локально (HS256 вашим jwt_secret) без сети

// Node.js
const jwt = require("jsonwebtoken");
const claims = jwt.verify(token, process.env.APPLOGIN_JWT_SECRET, {
  algorithms: ["HS256"], audience: "app_xxx", issuer: "applogin"
});
// claims.sub — user id, claims.email, claims.email_verified

# Python
import jwt
claims = jwt.decode(token, APPLOGIN_JWT_SECRET, algorithms=["HS256"],
                    audience="app_xxx", issuer="applogin")
Локальная проверка не видит мгновенный отзыв сессии (logout). Нужен мгновенный отзыв — используйте /v1/session/verify.

Структура JWT

{
  "iss": "applogin",
  "aud": "app_xxx",          // your app_id
  "sub": "2",                // user id (as a string)
  "jti": "…",                // session id (for revocation)
  "email": "user@example.com",
  "email_verified": true,
  "name": "Jane", "picture": null,
  "iat": 1782194619, "exp": 1784786619   // ~30 days
}

Вебхук (опционально)

Если задать у приложения webhook_url, платформа при успешном входе через Google шлёт на него подписанный POST с проверенной личностью — для серверной синхронизации в дополнение к токену.

ЗаголовокЗначение
X-Applogin-Timestampunix-ms
X-Applogin-Signaturesha256=<hex> от timestamp + "." + rawBody
const exp = "sha256=" + crypto.createHmac("sha256", WEBHOOK_SIGNING_SECRET)
  .update(ts + "." + rawBody).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(exp), Buffer.from(sig))) reject();

Создание приложения

Приложения создаются в закрытом дашборде applogin.one/dashboard (вход — через сам Applogin). При создании вы указываете:

ПолеЗачем
nameПоказывается в форме входа («Вход · <name>»).
allowed_originsOrigin'ы, которым разрешено встраивать форму и получать токены. Укажите домен приложения + домен-обёртку (напр. дока).
redirect_urisДля Google-входа: https://applogin.one/auth-callback.html.
webhook_url(опц.) куда слать вебхук о входе.

Выдаются: app_id (публичный), jwt_secret (для проверки токена на бэкенде), client_secret, webhook_signing_secret.

REST API — справочник

База: https://applogin.one/api. Ниже — что реально нужно билдеру. Ручки email/пароля и Google-обмена дёргает сама hosted-форма, вам их вызывать не нужно.

Для билдера

POST/v1/session/verify

Проверить app-токен на бэкенде (с учётом отзыва). { app_id, token }{ valid, user }.

GET/v1/app/public

Публичные данные приложения (name, allowed_origins). Использует hosted-страница входа.

Внутренние (дёргает hosted-форма/SDK, не билдер)

РучкаРоль
POST /v1/email/register · verify · resend · login · reset/request · reset/confirm · password/changeemail/пароль — вызывается из hosted-формы /login.
POST /v1/auth/start, GET /oauth/google/callback, POST /v1/auth/exchangeGoogle OAuth (внутри hosted-формы).
POST /v1/session/ssoТихий SSO (дёргает /session из скрытого iframe).
POST /v1/session/establishСтавит SSO-cookie в правильной партиции (после Google).
POST /v1/session/logoutОтзыв сессии (через SDK logout()).

Ошибки

HTTPКогда
400Неверный ввод (короткий пароль, истёкший/неверный код, «Email already registered»).
403«Invalid credentials», доступ запрещён, «Too many attempts» (рейт-лимит).
404Неизвестное приложение/маршрут.
{"error":"Invalid or expired code","message":"Invalid or expired code"}

Безопасность

Шпаргалка для LLM

Модель: вся авторизация — в iframe на applogin.one. Билдер НЕ рисует форму, НЕ шлёт пароль, НЕ проверяет коды. Билдер подключает SDK + виджет и получает app-токен.

// include
<script src=https://applogin.one/applogin.js?v=1></script>
<script src=https://applogin.one/applogin-ui.js?v=1></script>

// mount (a lock on the app)
ApploginUI.mount({ appId, onAuth:(user)=>..., onLogout:()=>... });
ApploginUI.logout();

// low level
Applogin.init({ appId });
await Applogin.getSession();   // {authenticated, token, user} — silent SSO
await Applogin.openLogin();    // {token, user, lang}|null — modal with the form
Applogin.getToken(); await Applogin.verify(); await Applogin.logout();

// backend: verify the token
POST https://applogin.one/api/v1/session/verify {app_id, token} -> {valid, user}
// or locally: jwt.verify(token, jwt_secret, {algorithms:["HS256"], audience:app_id, issuer:"applogin"})

SSO: вход ставит cookie al_sso (Partitioned, по top-level сайту). Приложения под одним сайтом (напр. в iframe дока appdock.pro) делят сессию; отдельный домен → вход заново. В allowed_origins приложения — его домен + домен-обёртка.

Токен app-scoped: iss=applogin, aud=app_id, sub=user id, подписан jwt_secret приложения.

Applogin · единая авторизация · дашборд · живой пример: AppDock