Applogin Dashboard

Applogin — inicio de sesión unificado

Añade el inicio de sesión con Google y correo/contraseña a tu aplicación con un solo script. Toda la autenticación — inicio de sesión, registro, verificación de correo, restablecimiento de contraseña, Google — ocurre dentro de un iframe protegido en applogin.one. Tu página nunca ve la contraseña del usuario y no valida nada: solo recibes un token limitado a tu app listo para usar.

Lo que la plataforma hace por ti
  • Pinta el formulario de inicio de sesión/registro (en su propio iframe) — tú no construyes ninguno.
  • Recibe la contraseña, comprueba las credenciales, envía y verifica los códigos por correo — tú no verificas nada.
  • Mantiene una cuenta por correo (Google y contraseña apuntan a la misma cuenta).
  • Mantiene una sesión entre aplicaciones y retoma el inicio de sesión entre tus apps en silencio.

Cómo funciona

Applogin es un proveedor de autenticación (como Auth0/Clerk), pero el formulario se sirve en un frame desde nuestro dominio. Tu app abre ese frame (en un modal) mediante el SDK y recibe el resultado por postMessage. El token es un JWT firmado con el secreto de tu aplicación (aud=app_id), por lo que es inútil en cualquier otra aplicación.

Tu aplicación (p. ej. emailwriter.online) │ applogin.js + applogin-ui.js (SDK / widget) │ abre un modal con un iframe: ▼ ┌──────────────────────────────────────────┐ │ iframe → https://applogin.one/login │ ← la contraseña se escribe AQUÍ │ (formulario: Google / correo+contraseña) │ tu JS nunca la ve └──────────────────────────────────────────┘ ▲ postMessage { token, user } (solo a tu origen) │ ▼ Recibes un token de app → lo verificas en tu backend (/v1/session/verify)
ConceptoQué es
Aplicación (app)Una entidad de la plataforma. Tiene un app_id público, un jwt_secret (verificación del token en el backend) y las listas allowed_origins / redirect_uris.
Usuario finalUna cuenta global (una por correo) compartida por todas las aplicaciones de la plataforma. Google y contraseña se vinculan a la misma cuenta.
Token de appJWT (HS256, aud=app_id) firmado con el jwt_secret de tu app. Respaldado por una sesión revocable.
Sesión SSOSesión global en la cookie HttpOnly+Partitioned al_sso en applogin.one. Compartida dentro de un mismo sitio de nivel superior.

Inicio rápido

Incluye dos scripts y monta el widget: intenta el SSO en silencio, muestra un botón «Iniciar sesión», abre el formulario alojado en un frame y devuelve el usuario.

<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>

Eso es todo. El formulario, el registro, los códigos por correo, Google y el restablecimiento de contraseña los gestiona Applogin. El único requisito: registrar un app_id e indicar tus allowed_origins (ver Crear una aplicación).

La versión ?v=1 en las URL de los scripts evita que el navegador sirva un SDK obsoleto de la caché tras una actualización.

El widget ApploginUI recomendado

Un «candado» listo para tu app: mientras no haya sesión, muestra una pantalla con el botón «Iniciar sesión»; al hacer clic abre el formulario alojado en un modal; tras el inicio llama a onAuth(user) y quita la pantalla.

MétodoDescripción
ApploginUI.mount({ appId, onAuth, onLogout, title? })Montar. Intenta el SSO silencioso; si no hay sesión, pinta la pantalla «Iniciar sesión».
ApploginUI.logout()Cerrar sesión (revoca la sesión y vuelve a la pantalla).
ApploginUI.getUser()El usuario actual o null.

El perfil (avatar, nombre, correo) y el botón de salir los pintas tú desde onAuth(user) — esa es tu UI. Los datos del usuario llegan listos.

Métodos del SDK (applogin.js) bajo nivel

Si quieres tu propia UX en vez del widget, usa el SDK directamente. Llama primero a Applogin.init({ appId }). El token se guarda en localStorage bajo al_token_<appId>.

MétodoDescripciónDevuelve
init({ appId })Inicialización.
getSession()SSO silencioso: retoma la sesión si el usuario inició en otra app del mismo sitio.{ authenticated, token, user }
openLogin()Abrir el modal del formulario alojado (iframe en applogin.one).{ token, user, lang } o null
verify()Comprobar el token actual.{ valid, user }
logout()Cerrar sesión (revoca la sesión y limpia el token).
getToken()El token de app actual.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

Inicio de sesión único (SSO)

Al iniciar sesión, Applogin pone la cookie al_sso con el atributo Partitioned. La clave de partición es el sitio de nivel superior (el más externo). Por lo tanto:

const s = await Applogin.getSession();   // ← {authenticated:true,…} if a session exists in this partition
if (s.authenticated) showApp(s.user);
El requisito de allowed_origins. El frame de inicio comprueba toda la cadena de ancestros (frame-ancestors), así que los allowed_origins de una app deben listar su propio dominio y el dominio contenedor (p. ej. appdock.pro).
Siendo honestos con el aislamiento. La separación «mismo sitio → SSO, otro nivel superior → iniciar de nuevo» la impone el navegador (particionado de cookies, CHIPS). En navegadores sin CHIPS la cookie puede comportarse como compartida — entonces el auto-inicio también ocurre en la página independiente de la app. No es un agujero: la emisión del token sigue limitada por allowed_origins (un sitio ajeno nunca obtiene un token).

Idiomas

El formulario de inicio alojado habla 10 idiomas: English, Deutsch, Français, Español, Italiano, Português, 日本語, 한국어, 中文, Русский. Por defecto se abre en el idioma del navegador del usuario (con inglés como respaldo); el idioma se cambia directamente en el formulario — el menú de banderas abajo.

Por debajo, la URL del formulario acepta ?lang=xx (código de dos letras de la lista de arriba) — el SDK lo pasa por ti.

Ejemplo en vivo: AppDock

appdock.pro es un lanzador tipo «dock»: una página que abre varias aplicaciones en iframes. Las aplicaciones viven en sus propios dominios:

AplicaciónDominioapp_id
Email Writeremailwriter.onlineapp_emailwriter
Audio Recorderaudiorecorder.infoapp_recorder

Inicia sesión en Email Writer dentro del dock y luego abre Audio Recorder (también dentro del dock): el inicio se retoma automáticamente, porque ambos corren bajo el mismo sitio de nivel superior appdock.pro y comparten una partición SSO.

1. El lanzador (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. Una aplicación (p. ej. 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. Registro de apps para este escenario

Cada aplicación lista en allowed_origins su propio dominio + el del dock (frame-ancestors ve toda la cadena de ancestros del frame anidado):

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"]
Comportamiento resultante: dentro del dock — un inicio compartido entre Email Writer y Audio Recorder; cada app por separado (su dominio como nivel superior) — un inicio nuevo. Las apps no contienen ningún formulario de inicio — solo ApploginUI.mount.

Verificar el token en tu backend

Tu frontend pone Applogin.getToken() en la cabecera Authorization de sus peticiones. En el backend hay dos formas de verificarlo.

1. Con el endpoint de la plataforma considera la revocación

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. En local (HS256 con tu jwt_secret) sin red

// 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")
La verificación local no ve una revocación instantánea de la sesión (logout). Si necesitas revocación instantánea, usa /v1/session/verify.

Estructura del 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 (opcional)

Si una aplicación define un webhook_url, la plataforma le envía un POST firmado con la identidad verificada en cada inicio con Google — para sincronización en el servidor además del token.

CabeceraValor
X-Applogin-Timestampunix-ms
X-Applogin-Signaturesha256=<hex> de 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();

Crear una aplicación

Las aplicaciones se crean en el panel privado applogin.one/dashboard (inicio de sesión con el propio Applogin). Debes indicar:

CampoPara qué
nameSe muestra en el formulario («Iniciar sesión · <name>»).
allowed_originsOrígenes autorizados a incrustar el formulario y recibir tokens. Lista el dominio de la app + el dominio contenedor (p. ej. el dock).
redirect_urisPara el inicio con Google: https://applogin.one/auth-callback.html.
webhook_url(opcional) adónde enviar el webhook de inicio.

Recibes: app_id (público), jwt_secret (verificación del token en el backend), client_secret, webhook_signing_secret.

API REST — referencia

Base: https://applogin.one/api. Abajo, lo que un integrador realmente necesita. Los endpoints de correo/contraseña y de intercambio de Google los llama el propio formulario alojado — tú nunca.

Para el integrador

POST/v1/session/verify

Verificar un token de app en tu backend (con revocación). { app_id, token }{ valid, user }.

GET/v1/app/public

Datos públicos de la aplicación (name, allowed_origins). Los usa la página de inicio alojada.

Internos (los llama el formulario alojado/SDK, no tú)

EndpointRol
POST /v1/email/register · verify · resend · login · reset/request · reset/confirm · password/changecorreo/contraseña — llamados desde el formulario alojado /login.
POST /v1/auth/start, GET /oauth/google/callback, POST /v1/auth/exchangeOAuth de Google (dentro del formulario alojado).
POST /v1/session/ssoSSO silencioso (lo llama /session desde un iframe oculto).
POST /v1/session/establishPone la cookie SSO en la partición correcta (después de Google).
POST /v1/session/logoutRevocación de la sesión (mediante el SDK logout()).

Errores

HTTPCuándo
400Entrada no válida (contraseña corta, código inválido/caducado, «Email already registered»).
403«Invalid credentials», acceso denegado, «Too many attempts» (límite de intentos).
404Aplicación/ruta desconocida.
{"error":"Invalid or expired code","message":"Invalid or expired code"}

Seguridad

Chuleta para LLM

Modelo: toda la autenticación ocurre en un iframe en applogin.one. El integrador NO pinta formularios, NO envía contraseñas, NO verifica códigos. Incluye SDK + widget y recibe un token de 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: el inicio pone la cookie al_sso (Partitioned, por sitio de nivel superior). Las apps bajo un mismo sitio (p. ej. iframes de un dock como appdock.pro) comparten la sesión; un dominio aparte → inicio nuevo. Los allowed_origins de una app = su dominio + el dominio contenedor.

El token está limitado a la app: iss=applogin, aud=app_id, sub=id de usuario, firmado con el jwt_secret de la app.

Applogin · inicio de sesión unificado · panel · ejemplo en vivo: AppDock