@alexec0de/id-widget
v0.1.0
Published
«Войти через alexec0de ID» — умная кнопка входа (OAuth2/OIDC + PKCE). Vanilla, React и Vue.
Maintainers
Readme
@alexec0de/id-widget
Умная кнопка «Войти через alexec0de ID» — OAuth 2.0 / OpenID Connect с PKCE.
Один пакет, три способа подключения: vanilla JS, React и Vue 3, плюс
готовый бандл для чистого HTML через <script>.
Что делает «умная» кнопка:
- При загрузке тихо проверяет сессию через скрытый iframe на домене провайдера.
- Показывает ник/аватар только если пользователь уже давал доступ этому приложению (иначе это утечка приватности — сервер это гарантирует).
- Если доступ уже выдан — кнопка меняется на «Продолжить как @nickname», и клик
уходит на авторизацию с
prompt=none— мгновенный вход без экрана согласия. - PKCE (S256) генерируется в браузере;
code_verifierиstateкладутся вsessionStorageдля обмена на токены на вашем бэкенде.
Установка
npm i @alexec0de/id-widgetReact / Vue — это peerDependencies (опциональные): ставится то, что уже есть в проекте.
baseUrlпо умолчанию —https://id.alexec0de.lol(канонический инстанс). Для него параметр можно не указывать; для своего развёртывания задайте свой origin.
React
import { AxidLoginButton } from "@alexec0de/id-widget/react";
export function LoginPage() {
return (
<AxidLoginButton
clientId="axid_ВАШ_CLIENT_ID"
baseUrl="https://id.example.com"
redirectUri="https://your.app/callback"
scope="openid profile email"
onStatus={(s) => console.log("session:", s)}
/>
);
}Через ref доступны refresh(), getStatus(), login():
const ref = useRef<AxidLoginButtonHandle>(null);
// ref.current?.login();Vue 3
<script setup lang="ts">
import { AxidLoginButton } from "@alexec0de/id-widget/vue";
</script>
<template>
<AxidLoginButton
client-id="axid_ВАШ_CLIENT_ID"
base-url="https://id.example.com"
redirect-uri="https://your.app/callback"
scope="openid profile email"
@status="(s) => console.log('session:', s)"
/>
</template>Чистый HTML (<script>, без сборки)
<div id="alexec0de-id-button"></div>
<script
src="https://unpkg.com/@alexec0de/id-widget/dist/axid-widget.global.js"
data-client-id="axid_ВАШ_CLIENT_ID"
data-base-url="https://id.example.com"
data-redirect-uri="https://your.app/callback"
data-scope="openid profile email"
></script>Полный API также доступен на window.AxidWidget.
Vanilla JS / TypeScript (программно)
import { mount } from "@alexec0de/id-widget";
const widget = mount("#login", {
clientId: "axid_ВАШ_CLIENT_ID",
baseUrl: "https://id.example.com",
redirectUri: "https://your.app/callback",
scope: "openid profile email",
});
// widget.refresh(); widget.getStatus(); widget.login(); widget.destroy();Обработка callback
На странице redirect_uri прочитайте код и PKCE-verifier, проверив state:
import { readCallback } from "@alexec0de/id-widget";
const result = readCallback();
if (result.ok) {
// Отправьте на СВОЙ бэкенд для обмена на токены (client_secret не в браузере!)
await fetch("/api/oauth/exchange", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code: result.code, codeVerifier: result.codeVerifier }),
});
} else {
console.error("OAuth error:", result.error, result.errorDescription);
}Ваш бэкенд делает POST {baseUrl}/oauth/token с grant_type=authorization_code,
code, redirect_uri, code_verifier и Basic-авторизацией client_id:client_secret.
Опции (AxidConfig)
| Поле | Тип | По умолчанию | Описание |
|---|---|---|---|
| clientId | string | — (обязательно) | client_id из дашборда |
| baseUrl | string | канонический инстанс | Origin провайдера alexec0de ID |
| redirectUri | string | — | Куда вернётся code (обязательно, если нет authorizeUrl) |
| scope | string | "openid profile" | Запрашиваемые scope через пробел |
| theme | "dark" \| "light" | "dark" | Тема кнопки |
| variant | "button" \| "icon" | "button" | Кнопка с текстом или только иконка |
| text | string | «Войти через alexec0de ID» | Подпись в дефолтном состоянии |
| authorizeUrl | string | — | Свой серверный старт флоу (PKCE на бэкенде); тогда redirectUri/sessionStorage не нужны |
| onStatus | (s) => void | — | Колбэк при получении статуса сессии |
| onBeforeRedirect | (url) => void | — | Колбэк перед переходом на провайдера |
HTML-атрибуты соответствуют опциям в kebab-case: data-client-id, data-base-url,
data-redirect-uri, data-scope, data-theme, data-variant, data-text,
data-authorize-url, data-target.
Требования
- Браузер с Web Crypto (
crypto.subtle) — то есть HTTPS илиlocalhost. - На стороне провайдера у приложения должен быть зарегистрирован точный
redirect_uri(сравнение побайтовое), а его origin — среди разрешённых для виджета.
Сборки в пакете
| Экспорт | Формат | Назначение |
|---|---|---|
| @alexec0de/id-widget | ESM + CJS + d.ts | vanilla-ядро |
| @alexec0de/id-widget/react | ESM + CJS + d.ts | React-компонент |
| @alexec0de/id-widget/vue | ESM + CJS + d.ts | Vue 3-компонент |
| dist/axid-widget.global.js | IIFE (window.AxidWidget) | <script> / CDN |
Лицензия
MIT
