Skip to content

Auth providers (app.authProviders)

Реестр внешних способов входа и backend API registerAuthProvider.

Backend

ts
import { defineExtension } from '@artiroute/extension-sdk/extension';

export default defineExtension((ctx) => {
  ctx.registerAuthProvider(
    { id: 'keycloak', title: 'Keycloak', kind: 'redirect', order: 10 },
    (auth) => {
      auth.registerRoute('GET', '/login', async (_req, res) => {
        // redirect to IdP
      });
      auth.registerRoute('GET', '/callback', async (req, res) => {
        const result = await auth.establishSession({ subject: '...' });
        res.redirect(result.redirectUrl);
      });
    }
  );
});

Маршруты доступны по prefix:

/api/auth/ext/{scopedProviderId}/...

scopedProviderId = {extensionSlug}:{providerId}, например auth-keycloak:keycloak.

Configuration

Auth extensions store IdP settings in the database via Extension settings. Configure them in Settings → Keycloak / LDAP (admin only). Env vars remain as a dev fallback only.

Frontend

ts
import {
  getExtensionRegistry,
  type ExtensionAuthProviderItem,
} from '@artiroute/extension-sdk/extension';
import { getProviderLoginUrl } from '@artiroute/host/auth';

getExtensionRegistry<ExtensionAuthProviderItem>('app.authProviders').register('keycloak__login', {
  id: 'auth-keycloak:keycloak',
  title: 'Keycloak',
  kind: 'redirect',
  async initiateLogin() {
    window.location.href = getProviderLoginUrl('auth-keycloak:keycloak', '/login');
  },
});

Form provider (LDAP)

Для kind: 'form' URL логина и редирект после сессии тоже должны учитывать BASE_URL (демо под /demo/):

ts
import { completeLogin, getProviderLoginUrl } from '@artiroute/host/auth';
import { withAppBase } from '@artiroute/host/api';

const PROVIDER_SCOPED_ID = 'auth-ldap:ldap';

async function submitLogin(username: string, password: string) {
  const response = await fetch(getProviderLoginUrl(PROVIDER_SCOPED_ID, '/login'), {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({ username, password }),
  });
  const payload = await response.json();
  completeLogin(payload.sessionToken);
  window.location.href = withAppBase('/dashboard');
}

Не используйте литералы '/api/auth/ext/...' — на стендах с BASE_URL=/demo запрос уйдёт в корень домена и вернёт 404.

Host callback

После успешной внешней авторизации хост выдаёт одноразовый code и редиректит на /auth/callback?code=.... Экран обменивает code на Keystone sessionToken.

Host API

@artiroute/host/auth:

  • completeLogin(sessionToken)
  • exchangeCodeAndLogin(code)
  • getAuthProviders()
  • getProviderLoginUrl(providerScopedId, path?)

AI workspace для командных материалов и знаний