왜 우리는 자체 호스팅 Clerk 대안을 만들었는가 (그리고 오픈소스화했다)
Source: Dev.to
위에 제공된 링크에 있는 전체 텍스트를 알려주시면, 해당 내용을 한국어로 번역해 드리겠습니다.
호스팅된 인증의 문제점
1. 가격이 매출보다 빠르게 상승
| 사용자 | Clerk | Auth0 | Authon |
|---|---|---|---|
| 10 000 | 무료 | ~ $700/mo | 무료 |
| 50 000 | ~ $825/mo | ~ $3 500/mo | 무료 |
| 100 000 | ~ $1 825/mo | 맞춤형 | 무료 |
| 500 000 | 맞춤형 | 맞춤형 | 무료 |
Clerk는 10 k를 초과하는 MAU당 $0.02를 청구하고, Auth0 Essentials는 $0.07/MAU를 청구합니다. 부트스트랩된 스타트업에게는 이 비용이 큰 부담이 됩니다. 인증은 사용자 수가 아니라 컴퓨팅 비용에 맞춰 확장돼야 합니다.
2. 공급업체 종속성은 실제 문제
@clerk/nextjs를 임포트하고 clerkClient.users.getUser()를 호출하면 코드가 Clerk에 묶이게 됩니다. 공급자를 바꾸려면 대대적인 재작성이 필요합니다.
Firebase Auth는 더 강하게 얽혀 있습니다: Firestore 보안 규칙이 request.auth를 참조하고, Cloud Functions가 인증 트리거를 사용하며, 사용자 ID가 Firebase 전용입니다. 이를 다른 서비스로 마이그레이션하는 데는 몇 주가 걸리는 프로젝트가 됩니다.
3. 데이터 주권
호스팅된 인증 서비스는 자격 증명, 세션, 개인 데이터를 제3자 서버에 저장합니다. 규제 산업(헬스케어, 금융)이나 데이터 프라이버시 법규가 엄격한 지역(EU)에서는 이는 종종 허용될 수 없습니다.
4. 우리가 필요로 했던 누락된 기능들
| 기능 | 기존 플랫폼이 부족했던 이유 |
|---|---|
| Web3 지갑 인증 | 네이티브 EVM 및 Solana 로그인 필요, 서드파티 플러그인으로는 해결되지 않음 |
| ShadowDOM‑격리 UI | 호스트 CSS와 충돌하지 않는 로그인 모달이 필요 |
| 15+ SDK | React, Vue, Svelte, Angular, React Native, Flutter, Python, Go, Swift, Kotlin 등 첫 번째 파티 지원이 필요 |
솔루션: Authon
Authon은 네 가지 원칙을 중심으로 구축된 독립형 인증 플랫폼입니다:
- 셀프‑호스팅, 언제나 무료 – 자체 서버에서 실행; 사용자당 비용이 없습니다.
- 드롭‑인 SDK – 한 줄 코드로 모든 프레임워크에 인증을 추가합니다.
- ShadowDOM 격리 – 로그인 모달이 캡슐화되어 CSS 충돌을 방지합니다.
- Web3 네이티브 – 지갑 인증이 사후 고려가 아닌 일급 시민으로 다뤄집니다.
Authon이 하는 일
인증 방법
- 이메일 / 비밀번호 (회원가입, 로그인, 비밀번호 재설정)
- OAuth (Google, Apple, GitHub, Discord, Facebook, Microsoft, Kakao, Naver, LINE, X)
- 비밀번호 없는 인증 (매직 링크, 이메일 OTP)
- Passkeys (WebAuthn) – 전체 라이프사이클: 등록, 인증, 목록 조회, 이름 변경, 폐기
- Web3 지갑 – EVM (MetaMask, WalletConnect, Coinbase Wallet, Trust Wallet) 및 Solana (Phantom)
보안
- MFA (TOTP) – Google Authenticator / Authy와 호환되며 백업 코드 제공
- 세션 관리 – 활성 세션 목록 조회, 개별 폐기 가능
- 감사 로그 – 모든 인증 이벤트가 기록됨
플랫폼 기능
- 조직 – 역할(소유자, 관리자, 멤버)과 함께하는 멀티테넌트 지원
- JWT 템플릿 – 사용자 정의 클레임 매핑
- 웹훅 – 서명된 페이로드를 포함한 10가지 이벤트 유형
- 브랜딩 – 전체 테마(색상, 로고, 사용자 정의 CSS, 로케일)
- 관리자 대시보드 – 사용자 관리, 분석, 설정
6개 언어에 걸친 15개의 SDK
| 플랫폼 | 패키지 |
|---|---|
| Vanilla JS | @authon/js |
| React | @authon/react |
| Next.js | @authon/nextjs |
| Vue 3 | @authon/vue |
| Nuxt 3 | @authon/nuxt |
| Svelte | @authon/svelte |
| Angular | @authon/angular |
| React Native | @authon/react-native |
| Node.js | @authon/node |
| Python | authon (PyPI) |
| Go | authon-go |
| Dart / Flutter | authon (pub.dev) |
| Swift (iOS/macOS) | Authon (SPM) |
| Kotlin (Android) | authon-kotlin (Maven) |
| CLI scaffolding | create-authon-app |
우리는 React용 SDK만 제공하고 다른 사람들은 스스로 해결하게 하고 싶지 않았습니다. Django, FastAPI, Gin, Flutter, SwiftUI 등으로 개발하든 — 첫 번째 파티 SDK가 있습니다.
How It Works
React Example
import {
AuthonProvider,
SignedIn,
SignedOut,
UserButton,
useAuthon,
} from '@authon/react';
function App() {
return (
<AuthonProvider>
<SignedIn>
<UserButton />
</SignedIn>
<SignedOut>
<SignInButton />
</SignedOut>
</AuthonProvider>
);
}
function SignInButton() {
const { openSignIn } = useAuthon();
return <button onClick={openSignIn}>Sign in</button>;
}openSignIn()은 대시보드에서 설정한 모든 제공자를 포함하는 ShadowDOM 모달을 렌더링합니다.
Next.js Middleware
import { authMiddleware } from '@authon/nextjs';
export default authMiddleware({
publicRoutes: ['/', '/sign-in', '/pricing'],
});
export const config = {
matcher: ['/((?!_next|.*\\..*).*)'],
};세 줄의 설정만으로 모든 비공개 라우트를 보호합니다.
Express Backend
import { expressMiddleware } from '@authon/node';
app.use(
'/api',
expressMiddleware({
secretKey: process.env.AUTHON_SECRET_KEY!,
})
);
app.get('/api/profile', (req, res) => {
res.json({ user: req.auth });
});미들웨어가 JWT를 검증하고, 사용자를 디코딩한 뒤 req.auth에 연결합니다.
Web3 Sign‑In
const authon = new Authon('pk_live_...');
// 1️⃣ Get a nonce for the wallet to sign
const { message } = await authon.web3GetNonce(address, 'evm', 'metamask');
// 2️⃣ User signs the message in MetaMask
const signature = await ethereum.request({
method: 'personal_sign',
params: [message, address],
});
// 3️⃣ Verify the signature and obtain a session
const user = await authon.web3Verify(
message,
signature,
address,
'evm',
'metamask'
);타사 플러그인이나 추가 서비스 없이 네이티브 지갑 인증만으로 구현됩니다.
Authon은 인증 비용, 데이터 주권, 기능 세트에 대한 완전한 제어권을 제공하면서도 주요 플랫폼 전반에 걸쳐 통합을 간단하게 유지합니다. 🚀
Plex Integrations
Web3 인증은 핵심 SDK에 내장되어 있습니다.
ShadowDOM: 왜 중요한가
대부분의 인증 솔루션은 UI를 직접 DOM에 주입하거나 iframe을 사용합니다. 두 방법 모두 문제점이 있습니다:
- 직접 DOM 주입 – 앱의 CSS가 인증 모달에 영향을 줄 수 있습니다.
* { box-sizing: border-box; }규칙, 전역 폰트 재정의, 혹은 높은 z‑index 요소가 로그인 폼을 깨뜨릴 수 있습니다. - Iframe – 작동은 하지만 UX 마찰을 일으킵니다 (스크롤 컨텍스트가 다르거나 일부 브라우저에서 차단되고, 테마 적용이 어려움).
Authon은 ShadowDOM을 사용합니다. 모달은 완전히 앱 스타일과 격리된 shadow root 안에 렌더링됩니다. 여러분의 CSS가 새어 들어올 수 없고, 모달의 스타일도 새어 나가지 않습니다. 매번 그대로 작동합니다.
비교
| Feature | Authon | Clerk | Auth0 | Auth.js | Firebase Auth | Supabase Auth |
|---|---|---|---|---|---|---|
| 셀프‑호스팅 | 예 | 아니오 | 아니오 | 해당 없음 (라이브러리) | 아니오 | 예 |
| 무료 무제한 사용자 | 예 | 아니오 (10K) | 아니오 (25K) | 예 | 부분 | 부분 |
| Web3 | 예 | 아니오 | 아니오 | 아니오 | 아니오 | 아니오 |
| 패스키 | 예 | 예 | 예 | 실험적 | 제한적 | 아니오 |
| MFA | 예 | 예 | 예 | 아니오 | 유료 | 예 |
| 조직 | 예 | 예 | 예 (유료) | 아니오 | 아니오 | 아니오 |
| ShadowDOM UI | 예 | 아니오 | 아니오 | 아니오 | 아니오 | 아니오 |
| SDK 수 | 15 | 8 | 20+ | 5 | 10+ | 6 |
| 미리 구축된 UI | 예 | 예 | 범용 로그인 | 아니오 | FirebaseUI | 기본 |
오픈 소스
Authon SDK는 MIT‑라이선스를 사용하며 GitHub에서 이용할 수 있습니다:
git clone https://github.com/mikusnuz/authon-sdk.git
cd authon-sdk
pnpm install
pnpm build시작하기
Authon을 가장 빠르게 체험하는 방법
npx create-authon-app my-app --framework nextjs이 명령은 Authon이 사전 설정된 Next.js 앱(프로바이더, 미들웨어, 로그인 페이지, 대시보드)을 자동으로 생성합니다.
수동으로 설치하기
npm install @authon/nextjs @authon/js- 문서: (link pending)
- GitHub: (link pending)
- 웹사이트: (link pending)
다음 단계
우리는 현재 활발히 개발 중입니다:
- SMS/전화 인증
- SAML 및 OIDC 연동
- 익명 인증
- 속도 제한 및 봇 탐지
- 더 많은 OAuth 제공자
사용자당 인증 비용을 지불하는 것이 지겹거나, 자체 호스팅 패키지에서 Web3/패스키/MFA가 필요하다면 Authon을 사용해 보세요. 여러분의 피드백을 기다립니다.