새 시스템은 애플리케이션을 등록하고, Discovery 문서를 읽은 뒤 표준 OAuth 2.0 흐름을 구현하거나 @tigrison/authhub-client SDK를 설치해 연동하세요. 액세스 토큰은 RS256 JWT이며 JWKS로 검증합니다.
Upstream (Federation) — 티그리스 등 외부 IdP 로그인은 AuthHub /login 또는 /auth/broker/tigris로 처리합니다. User·Tenant·조직도 매핑은 AuthHub가 담당합니다.
Downstream (일반 SSO) — 브라우저에서 AuthHub에 로그인할 때는 authorization_code(+PKCE)·SDK를 사용합니다.
외부 세션 교환 — 티그리스 앱 런처처럼 upstream이 _tigris_sid 등을 붙여 앱을 열 때는, 앱 서버가 grant_type=external_session+ provider 또는 SDK exchangeExternalSession()로 토큰을 받습니다. IdP가 늘어나도 API는 같고 provider만 추가합니다. confidential·서버 전용이며, 성공 후 URL에서 세션 쿼리를 제거하세요.
조직도 provider (directoryProvider) 와 로그인 IdP (allowedIdentityProviders)는 콘솔 사이트 설정에서 별도로 관리합니다.
npm install @tigrison/authhub-client
import { createAuthHubClient } from "@tigrison/authhub-client";
const authhub = createAuthHubClient({
issuer: "http://127.0.0.1:43177",
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
redirectUri: "https://your-app.example/callback",
scopes: ["openid", "profile", "email", "offline_access"],
});
// 서비스 토큰
const serviceTokens = await authhub.exchangeClientCredentials();
// 로그인 URL (PKCE)
const { codeVerifier, codeChallenge } = await authhub.createPkce();
const loginUrl = authhub.buildAuthorizationUrl({ codeChallenge });
// JWT 검증
import { verifyAccessToken } from "@tigrison/authhub-client/verify";
const claims = await verifyAccessToken(accessToken, {
issuer: "http://127.0.0.1:43177",
audience: "YOUR_CLIENT_ID",
});
// 사용자 디렉토리 (directory:read)
const dirTokens = await authhub.exchangeClientCredentials({
scope: "openid directory:read",
});
const directory = await authhub.listDirectoryUsers(dirTokens.access_token, {
limit: 20,
});
// 기본 아바타 목록 (인증 불필요) — TeamWiki 등 선택 UI용 절대 URL
const { presets } = await authhub.listAvatarPresets();
// presets[0].picture → http://127.0.0.1:43177/avatars/presets/01.webp
// 선택·업로드 (사용자 액세스 토큰)
await authhub.setAvatarPreset(accessToken, presets[0].id);
await authhub.uploadAvatar(accessToken, avatarFile);
const me = await authhub.getUserInfo(accessToken);
// me.picture
// Tenant 조직도 (directoryToken + siteId)
const siteAuth = createAuthHubClient({
issuer: "http://127.0.0.1:43177",
clientId: "YOUR_CLIENT_ID",
directoryToken: process.env.AUTHHUB_DIRECTORY_TOKEN,
siteId: "YOUR_SITE_ID",
});
const { orgUnits } = await siteAuth.listOrgUnits();
const { members } = await siteAuth.listOrgUnitMembers("DEPT_CODE");?_tigris_sid=...로 앱을 열면 서버에서 exchangeExternalSession만 호출합니다. 일반 SSO는 authorization_code를 사용하세요.import { createAuthHubClient } from "@tigrison/authhub-client";
// Route Handler / Server Action — 브라우저에 session·secret 금지
const authhub = createAuthHubClient({
issuer: "http://127.0.0.1:43177",
clientId: process.env.AUTHHUB_CLIENT_ID!,
clientSecret: process.env.AUTHHUB_CLIENT_SECRET!,
scopes: ["openid", "profile", "email", "offline_access"],
});
const tokens = await authhub.exchangeExternalSession({
provider: "tigris",
session: tigrisSid, // searchParams._tigris_sid
siteId, // 티그리스가 넘기면
scope: ["openid", "profile", "email", "offline_access"],
});
// httpOnly 쿠키 등에 저장 후 URL에서 _tigris_sid 제거exchangeExternalSession() / grant_type=external_session(provider로 IdP 구분)로 교환합니다.listAvatarPresets())로 미모지 목록·절대 URL을 받고, 적용만 사용자 토큰으로 setAvatarPreset()합니다.picture는 절대 URL입니다. Discovery의 avatar_presets_endpoint와 동일합니다.import { createAuthHubClient } from "@tigrison/authhub-client";
const authhub = createAuthHubClient({
issuer: "http://127.0.0.1:43177",
clientId: "YOUR_CLIENT_ID",
});
// 목록·절대 URL (인증 없음)
const { presets } = await authhub.listAvatarPresets();
const listUrl = await authhub.getAvatarPresetsEndpoint();
// 적용 (사용자 액세스 토큰)
await authhub.setAvatarPreset(accessToken, presets[0].id);curl -s http://127.0.0.1:43177/.well-known/openid-configuration