Applogin Dashboard

Applogin — 統合サインイン

スクリプト1つで、アプリに Google とメール/パスワードのサインインを追加できます。すべての認証 — サインイン、登録、メール確認、パスワードリセット、Google — は applogin.one 上の保護された iframe 内で行われます。あなたのページはユーザーのパスワードを一切見ることなく、何も検証しません。受け取るのは、すぐ使えるアプリ限定トークンだけです。

プラットフォームが代わりに行うこと
  • サインイン/登録フォームの描画(独自の iframe 内)— あなたが作る必要はありません
  • パスワードの受け取り、認証情報の確認、メールコードの送信と検証 — あなたは何も検証しません
  • メールアドレスごとに1つのアカウントを管理(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 / メール+パスワード) │ あなたの JS は見えない └──────────────────────────────────────────┘ ▲ postMessage { token, user } (あなたのオリジンにのみ) │ ▼ アプリトークンを受け取る → バックエンドで検証 (/v1/session/verify)
概念説明
アプリケーション (app)プラットフォーム上のエンティティ。公開の app_idjwt_secret(バックエンドでのトークン検証用)、allowed_origins / redirect_uris のリストを持ちます。
エンドユーザープラットフォームの全アプリで共有されるグローバルアカウント(メールごとに1つ)。Google とパスワードは同じアカウントに紐づきます。
アプリトークンあなたのアプリの jwt_secret で署名された JWT(HS256、aud=app_id)。失効可能なセッションに裏付けられています。
SSO セッションapplogin.one 上の HttpOnly+Partitioned クッキー al_sso に入るグローバルセッション。同じトップレベルサイト内で共有されます。

クイックスタート

スクリプトを2つ読み込んでウィジェットをマウントするだけ。静かに SSO を試し、「サインイン」ボタンを表示し、ホスト型フォームをフレームで開いてユーザーを返します。

<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 の設定だけです(アプリの作成参照)。

スクリプト URL の ?v=1 は、更新後にブラウザがキャッシュ済みの古い SDK を返すのを防ぎます。

ApploginUI ウィジェット 推奨

アプリの「鍵」として使える既製品:未サインイン時は「サインイン」ボタン付きの画面を表示し、クリックでホスト型フォームをモーダルで開き、サインイン後は onAuth(user) を呼んで画面を外します。

メソッド説明
ApploginUI.mount({ appId, onAuth, onLogout, title? })マウント。静かに SSO を試し、未サインインなら「サインイン」画面を表示。
ApploginUI.logout()サインアウト(セッションを失効し、画面を再表示)。
ApploginUI.getUser()現在のユーザー、または null

プロフィール(アバター、名前、メール)とサインアウトボタンは onAuth(user) からあなたが描画します — それがあなたの UI です。ユーザーデータはそのまま使えます。

SDK メソッド(applogin.js低レベル

ウィジェットではなく独自の UX が欲しい場合は SDK を直接使います。まず Applogin.init({ appId }) を呼びます。トークンは localStorageal_token_<appId> に保存されます。

メソッド説明戻り値
init({ appId })初期化。
getSession()静かな SSO:同じサイトの別アプリでサインイン済みならセッションを引き継ぐ。{ authenticated, token, user }
openLogin()ホスト型ログインフォームのモーダルを開く(applogin.one 上の iframe)。{ token, user, lang } または null
verify()現在のトークンを検証。{ valid, user }
logout()サインアウト(セッション失効+トークン削除)。
getToken()現在のアプリトークン。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 は Partitioned 属性付きのクッキー al_sso を設定します。パーティションのキーはトップレベルサイト(最も外側)です。したがって:

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、別のトップレベル → 再サインイン」の区別はブラウザ(クッキーのパーティショニング、CHIPS)が強制します。CHIPS 非対応のブラウザではクッキーが共有のように振る舞うことがあり、その場合はアプリの単独ページでも自動ログインが起こります。これは穴ではありません:トークンの発行は引き続き allowed_origins でゲートされます(無関係なサイトはトークンを得られません)。

言語

ホスト型ログインフォームは10言語に対応しています:English, Deutsch, Français, Español, Italiano, Português, 日本語, 한국어, 中文, Русский。デフォルトではユーザーのブラウザ言語で開き(フォールバックは英語)、フォーム内で言語を切り替えられます — 下部の国旗メニューです。

内部的にはフォームの URL が ?lang=xx(上記リストの2文字コード)を受け付けます — SDK が自動で付与します。

ライブ例:AppDock

appdock.pro は「ドック」型ランチャー:1つのページから複数のアプリを iframe で開きます。アプリはそれぞれ独自ドメインにあります:

アプリケーションドメインapp_id
Email Writeremailwriter.onlineapp_emailwriter
Audio Recorderaudiorecorder.infoapp_recorder

ドック内で Email Writer にサインインし、次に(同じくドック内の)Audio Recorder を開くと、サインインは自動的に引き継がれます。両方が同じトップレベルサイト appdock.pro の下で動き、1つの 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 のサインインが共有され、各アプリを単独で開く(自ドメインがトップレベル)と新規サインイン。アプリ自身はログインフォームを一切持たずApploginUI.mount だけです。

バックエンドでのトークン検証

フロントエンドはリクエストの Authorization ヘッダーに Applogin.getToken() を入れます。バックエンドでの検証方法は2つです。

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. ローカルで(あなたの jwt_secret による HS256)ネット不要

// 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")
ローカル検証では即時のセッション失効(ログアウト)は見えません。即時失効が必要なら /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(任意)

アプリに webhook_url を設定すると、Google サインインの成功のたびに、検証済みの ID を含む署名付き POST がそこへ送られます — トークンに加えたサーバー側同期のためです。

ヘッダー
X-Applogin-Timestampunix-ms
X-Applogin-Signaturetimestamp + "." + rawBodysha256=<hex>
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_originsフォームの埋め込みとトークン受信を許可するオリジン。アプリのドメイン+ラッパードメイン(例:ドック)を列挙。
redirect_urisGoogle サインイン用:https://applogin.one/auth-callback.html
webhook_url(任意)サインイン Webhook の送信先。

受け取るもの:app_id(公開)、jwt_secret(バックエンドでのトークン検証)、client_secretwebhook_signing_secret

REST API — リファレンス

ベース:https://applogin.one/api。以下は開発者が実際に必要とするものです。メール/パスワードや Google 交換のエンドポイントはホスト型フォーム自身が呼び、あなたは呼びません。

開発者向け

POST/v1/session/verify

バックエンドでアプリトークンを検証(失効考慮)。{ app_id, token }{ valid, user }

GET/v1/app/public

アプリの公開データ(nameallowed_origins)。ホスト型ログインページが使用。

内部用(ホスト型フォーム/SDK が呼ぶ。あなたは呼ばない)

エンドポイント役割
POST /v1/email/register · verify · resend · login · reset/request · reset/confirm · password/changeメール/パスワード — ホスト型フォーム /login から呼ばれる。
POST /v1/auth/start, GET /oauth/google/callback, POST /v1/auth/exchangeGoogle OAuth(ホスト型フォーム内)。
POST /v1/session/sso静かな SSO(隠し iframe から /session が呼ぶ)。
POST /v1/session/establish正しいパーティションに SSO クッキーを設定(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 向けチートシート

モデル:すべての認証は applogin.one の iframe 内で行われる。開発者はフォームを描画せず、パスワードを送らず、コードを検証しない。SDK + ウィジェットを読み込み、アプリトークンを受け取る。

// 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:サインインはクッキー al_sso(Partitioned、トップレベルサイト単位)を設定する。同じサイトの下のアプリ(例:appdock.pro のようなドックの iframe)はセッションを共有。別ドメイン → 再サインイン。アプリの allowed_origins = 自ドメイン + ラッパードメイン。

トークンはアプリ限定:iss=apploginaud=app_idsub=ユーザー ID、アプリの jwt_secret で署名。

Applogin · 統合サインイン · ダッシュボード · ライブ例:AppDock