Documentation
Introduction
Shoo is a free, open-source OAuth provider that lets you add secure authentication to any application in minutes. No signup required, no API keys, no backend needed.
Point your redirect URI to shooauth.com and go. Shoo handles the OAuth flow, identity tokens, and session management. You get verified user identities via JWT.
Quick Start
Add Shoo to any app with just 2 lines of code. Works with React, Vue, vanilla JS, or any framework.
1<!-- 1. Add the script -->2<script src="https://shooauth.com/shoo.js"></script>34<!-- 2. Add a login link -->5<a href="https://shooauth.com/sign-in?redirect_uri=https://yourapp.com/callback">6 Login7</a>
SDK Installation
For React apps, use our official SDK for a smoother integration with hooks and automatic session management.
1# Install the Shoo React SDK2bun add @shoojs/react @shoojs/auth34# Or use the CDN (works with any framework)5<script src="https://cdn.jsdelivr.net/npm/@shoojs/auth"></script>
OAuth with Shoo
Shoo provides OAuth/OpenID Connect authentication. Users are redirected to shooauth.com to complete sign-in, then returned to your application with a verified identity token.
1// Sign in with Shoo (redirects to shooauth.com)2await signIn({ requestPii: true }); // Request name/email34// Or minimal sign-in (just userId)5await signIn();
Session Management
Shoo handles sessions automatically. Tokens are stored in localStorage and refreshed as needed. The React SDK provides automatic session monitoring.
1const { sessionState, checkSession } = useShooAuth();23// Session states: "unknown" | "active" | "login_required"4if (sessionState === "login_required") {5 // Redirect to sign in6}78// Explicitly check session validity9const result = await checkSession();10// { status: "active" } | { status: "login_required", reason: "expired" | "revoked" | "invalid_token" }
OAuth Callback
Create a callback page to handle the OAuth redirect. Works in any framework.
1// Next.js, React, or any framework2import { useShooAuth } from "@shoojs/react";34export default function Callback() {5 const { handleCallback } = useShooAuth();67 useEffect(() => {8 handleCallback({ redirectAfter: false })9 .then((token) => {10 if (token?.id_token) {11 // Token contains: pairwise_sub, email, name (if requested)12 window.location.href = "/dashboard";13 }14 });15 }, []);1617 return <div>Signing in...</div>;18}
useShooAuth Hook
The primary hook for interacting with Shoo Auth. Provides authentication state, sign-in methods, and user identity information.
1interface UseShooAuthReturn {2 identity: ShooIdentity; // { userId: string | null; token?: string; expiresIn?: number; }3 claims: IdentityClaims | null; // Decoded JWT claims (pairwise_sub, email, name, etc.)4 loading: boolean;5 sessionState: "unknown" | "active" | "login_required";6 error: string | null;7 // Actions8 signIn: (options?: StartSignInOptions) => Promise<void>;9 handleCallback: (options?: HandleCallbackOptions) => Promise<TokenResponse | null>;10 checkSession: () => Promise<SessionCheckResult>;11 refreshIdentity: () => void;12 clearIdentity: () => void;13 // Client reference14 authClient: ShooAuthClient | null;15}
Configuration Options
1useShooAuth({2 shooBaseUrl: "https://shooauth.com", // Shoo OAuth server3 callbackPath: "/auth/callback", // OAuth callback route4 autoHandleCallback: true, // Auto-process callback params5 autoSessionMonitor: true, // Enable background session checks6 sessionMonitorIntervalMs: 60000, // Check interval (default: 60s)7});
signIn
Initiates the OAuth authentication flow by redirecting to Shoo. After successful authentication, the user is redirected back to your callback path.
1interface StartSignInOptions {2 requestPii?: boolean; // Request personal info (name, email)3 returnTo?: string; // Path to redirect after sign-in4 redirectUri?: string; // Override the OAuth redirect URI5 clientId?: string; // Override the OAuth client ID6 shooBaseUrl?: string; // Override the Shoo server URL7}
OAuth Callback Handler
Handle the OAuth callback after the user returns from Shoo. Exchange the authorization code for tokens and establish the session.
The handleCallback method is available from the React hook. For direct client usage, use finishSignIn from the auth client.
1"use client";23import { useEffect } from "react";4import { useShooAuth } from "@shoojs/react";56export default function AuthCallback() {7 const { handleCallback } = useShooAuth();89 useEffect(() => {10 handleCallback({ redirectAfter: false })11 .then((token) => {12 if (token) {13 // Verify token with your backend14 window.location.href = "/dashboard";15 }16 });17 }, [handleCallback]);1819 return <div>Completing sign-in...</div>;20}
Clear Identity / Sign Out
Clear the local session. Shoo is stateless — there's no server-side session to invalidate.
1const { clearIdentity } = useShooAuth();23// Clear local session4clearIdentity();
Token Verification
Verify Shoo ID tokens server-side using JWKS. The tokens are JWTs signed by Shoo's keys and contain the user's pairwise_sub claim (unique per app).
1import { createRemoteJWKSet, jwtVerify } from "jose";23const jwks = createRemoteJWKSet(4 new URL("/.well-known/jwks.json", "https://shooauth.com")5);67// In your API route8export async function POST(request: Request) {9 const { idToken } = await request.json();1011 const { payload } = await jwtVerify(idToken, jwks, {12 issuer: "https://shooauth.com",13 audience: "origin:https://yourdomain.com",14 });1516 // payload.pairwise_sub contains the unique user ID17 return Response.json({ userId: payload.pairwise_sub });18}
Environment Setup
No environment variables required for basic usage. Just point your redirect URI to shooauth.com. For the React SDK, you can optionally configure the base URL.
1// Optional: Configure SDK (defaults shown)2useShooAuth({3 shooBaseUrl: "https://shooauth.com",4 callbackPath: "/auth/callback",5});
Security
Shoo implements OAuth 2.0 with PKCE and OpenID Connect:
- Pairwise user IDs (privacy-preserving, different per app)
- JWKS-based JWT verification with RS256 signatures
- Origin-bound tokens (audience validation prevents cross-site replay)
- PKCE flow for OAuth authorization code exchange
- 30-day token expiration
- No backend required — Shoo handles all OAuth server-side