1Clerk 프로젝트 설정
- clerk.com 에서 무료 계정 생성
- Create application 클릭
- 앱 이름 입력 (예: My React App)
- 로그인 방식 선택 (Email, Google, GitHub 등)
- API Keys에서
Publishable key복사
2React 앱 연동
패키지 설치
터미널
npm install @clerk/clerk-react환경 변수 설정
.env.local
# .env.local
VITE_CLERK_PUBLISHABLE_KEY=pk_test_xxx...ClerkProvider 설정
main.tsx
// main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ClerkProvider } from '@clerk/clerk-react';
import App from './App';
import './index.css';
const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
if (!PUBLISHABLE_KEY) {
throw new Error('Missing Publishable Key');
}
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<ClerkProvider publishableKey={PUBLISHABLE_KEY}>
<App />
</ClerkProvider>
</React.StrictMode>
);환경 변수 주의
Vite를 사용하는 경우 환경 변수 이름이 VITE_로 시작해야 합니다.
Next.js는 NEXT_PUBLIC_을 사용합니다.
3인증 UI 컴포넌트
Clerk은 바로 사용할 수 있는 UI 컴포넌트를 제공합니다.
components/AuthButtons.tsx
// components/AuthButtons.tsx
import {
SignedIn,
SignedOut,
SignInButton,
SignUpButton,
UserButton,
} from '@clerk/clerk-react';
export function AuthButtons() {
return (
<div className="flex items-center gap-4">
<SignedOut>
<SignInButton mode="modal">
<button className="px-4 py-2 bg-blue-600 text-white rounded-lg">
로그인
</button>
</SignInButton>
<SignUpButton mode="modal">
<button className="px-4 py-2 border border-gray-300 rounded-lg">
회원가입
</button>
</SignUpButton>
</SignedOut>
<SignedIn>
<UserButton afterSignOutUrl="/" />
</SignedIn>
</div>
);
}주요 컴포넌트
SignedIn- 로그인된 상태에서만 표시SignedOut- 로그아웃된 상태에서만 표시UserButton- 프로필 드롭다운 메뉴SignInButton- 로그인 버튼/모달SignUpButton- 회원가입 버튼/모달
4보호된 라우트 구현
로그인이 필요한 페이지를 보호하려면 ProtectedRoute 컴포넌트를 만듭니다.
components/ProtectedRoute.tsx
// components/ProtectedRoute.tsx
import { SignedIn, SignedOut, RedirectToSignIn } from '@clerk/clerk-react';
interface ProtectedRouteProps {
children: React.ReactNode;
}
export function ProtectedRoute({ children }: ProtectedRouteProps) {
return (
<>
<SignedIn>{children}</SignedIn>
<SignedOut>
<RedirectToSignIn />
</SignedOut>
</>
);
}5사용자 정보 접근
useUser 훅으로 현재 로그인한 사용자 정보에 접근할 수 있습니다.
components/UserProfile.tsx
// components/UserProfile.tsx
import { useUser } from '@clerk/clerk-react';
export function UserProfile() {
const { isLoaded, isSignedIn, user } = useUser();
if (!isLoaded) {
return <div>로딩 중...</div>;
}
if (!isSignedIn) {
return <div>로그인이 필요합니다</div>;
}
return (
<div className="p-4 bg-white rounded-lg shadow">
<img
src={user.imageUrl}
alt={user.fullName || '프로필'}
className="w-16 h-16 rounded-full"
/>
<h2 className="mt-2 text-lg font-bold">{user.fullName}</h2>
<p className="text-gray-600">{user.primaryEmailAddress?.emailAddress}</p>
</div>
);
}6백엔드 API 연동 (선택)
백엔드 API를 호출할 때 인증 토큰을 포함하려면 useAuth 훅을 사용합니다.
hooks/useAuthenticatedFetch.ts
// hooks/useAuthenticatedFetch.ts
import { useAuth } from '@clerk/clerk-react';
export function useAuthenticatedFetch() {
const { getToken } = useAuth();
return async (url: string, options: RequestInit = {}) => {
const token = await getToken();
return fetch(url, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
});
};
}
// 사용 예시
// const authFetch = useAuthenticatedFetch();
// const data = await authFetch('/api/projects');백엔드에서 토큰 검증
server.js
// 백엔드 (Node.js/Express 예시)
import { ClerkExpressRequireAuth } from '@clerk/clerk-sdk-node';
// 미들웨어로 토큰 검증
app.get('/api/protected',
ClerkExpressRequireAuth(),
(req, res) => {
// req.auth.userId로 사용자 ID 접근 가능
res.json({ userId: req.auth.userId });
}
);언제 Clerk을 선택할까요?
다음 단계
- UI 커스터마이징 - 브랜드에 맞게 스타일 변경
- Organizations - 팀/조직 기능 추가
- Supabase 연동 - 데이터베이스와 함께 사용