# Login with Astrina — integration guide

Astrina is the single sign-on broker for the ecosystem. Configure your social-login
providers **once** in Astrina; every site reuses them.

```
  Site  ──(1) redirect──▶  astrina.io/auth/authorize.php  ──▶  provider (Google…)
   ▲                                    │                              │
   └──(3) ?code=…&state=… ◀──── astrina.io/auth/cb.php ◀──(2) callback ─┘
   │
   └──(4) POST code ──▶ astrina.io/auth/token.php ──▶ { sub, email, name, avatar }
```

## One-time owner setup (in Astrina admin)

1. Open **`/admin/auth-providers.php`** (owner login, role ≥ 9).
2. For each provider you want, create an OAuth app in that provider's console and
   register **exactly** this redirect URI:
   - Google → `https://astrina.io/auth/cb.php?provider=google`
   - Yandex → `https://astrina.io/auth/cb.php?provider=yandex`
   - Apple → `https://astrina.io/auth/cb.php?provider=apple`
   - Telegram → create a bot with **@BotFather**, then `/setdomain` → `astrina.io`
3. Paste each app's **Client ID + Secret** (Telegram: **bot username + bot token**),
   tick **Enabled**, Save.
4. Under **Client sites**, register each site (name + allowed redirect URLs). Copy the
   `client_id` + `client_secret` shown **once**.

## Per-site integration (3 steps)

1. Copy `sdk.php` into the site and set four constants:

   ```php
   define('ASTRINA_CLIENT_ID',     'astr_xxxxxxxx');
   define('ASTRINA_CLIENT_SECRET', '…');   // server-side only, never in JS
   define('ASTRINA_REDIRECT_URI',  'https://mysite/auth/astrina-callback.php');
   require '/path/to/sdk.php';
   ```

2. Add the buttons anywhere. Either one "Login with Astrina" button (shows the
   chooser), or a row of **direct provider buttons** — a click on *Google* jumps
   straight into Google, no chooser page:

   ```php
   <!-- one button → Astrina chooser -->
   <a class="btn" href="<?= htmlspecialchars(AstrinaID::loginUrl()) ?>">Log in with Astrina</a>

   <!-- OR: direct per-provider buttons + the "Secured by Astrina ID" note -->
   <?= AstrinaID::buttonsHtml() ?>

   <!-- OR: hand-rolled, straight to one provider -->
   <a href="<?= htmlspecialchars(AstrinaID::loginUrl('google')) ?>">Continue with Google</a>
   ```

   `buttonsHtml()` fetches the providers you enabled in Astrina and renders exactly
   those, each deep-linked to the provider. Users land on Google/Yandex/… directly;
   the note keeps them oriented ("this sign-in is handled by Astrina").

3. Create the callback page (`astrina-callback.php`) at the redirect URL:

   ```php
   require 'config.php';           // defines the constants + sdk.php
   $u = AstrinaID::handleCallback();
   if (!$u) { header('Location: /login?e=1'); exit; }
   // key your local user on ($u['provider'], $u['sub']) — NOT email
   $local = find_or_create_user($u['provider'], $u['sub'], $u['email'], $u['name'], $u['avatar']);
   login($local); header('Location: /'); exit;
   ```

That's it — no per-site OAuth apps, no provider SDKs. Adding a new provider later is a
one-row change in Astrina; every site gets it automatically.

## Notes
- `sub` is a stable, opaque per-identity id. Treat email as informational (Telegram
  gives none; users can change it).
- The token response also carries an `id_token` (JWT HS256 signed with **your**
  client secret) if you prefer to verify locally instead of trusting the JSON.
- Codes are single-use and expire in 5 minutes; `state` is checked both by the SDK
  and by Astrina.
