@fcfmclub/auth
v1.1.13
Published
Paquete de autenticación OAuth propietario para aplicaciones FCFM Club
Maintainers
Readme
@fcfmclub/auth
Sistema de autenticación OAuth propietario para aplicaciones FCFM Club. Similar a NextAuth pero específicamente diseñado para la API de FCFM Club.
Instalación
npm install @fcfmclub/authConfiguración
1. Variables de entorno
Crea un archivo .env.local en tu proyecto Next.js:
# Requeridas
OAUTH_CLIENT_ID="tu-client-id"
OAUTH_CLIENT_SECRET="tu-client-secret"
# Opcional (para el cliente)
NEXT_PUBLIC_OAUTH_CLIENT_ID="tu-client-id"
NEXT_PUBLIC_API_URL="https://alpha.fcfm.club/api"2. Configurar ruta catch-all
Crea el archivo app/auth/[...fcfmauth]/route.ts:
Opción 1: Configuración simple (recomendada)
export { GET, POST } from "@fcfmclub/auth";Opción 2: Configuración personalizada
import { createFCFMAuth } from "@fcfmclub/auth";
import { NextRequest } from "next/server";
const fcfmAuth = createFCFMAuth({
apiUrl: process.env.NEXT_PUBLIC_API_URL || "https://alpha.fcfm.club/api",
successRedirect: "/dashboard", // Opcional
errorRedirect: "/auth/error", // Opcional
// clientId y clientSecret se toman automáticamente de las variables de entorno
});
export async function GET(
request: NextRequest,
{ params }: { params: { fcfmauth: string[] } },
) {
return fcfmAuth.handleAuth(request, params);
}
export async function POST(
request: NextRequest,
{ params }: { params: { fcfmauth: string[] } },
) {
return fcfmAuth.handleAuth(request, params);
}3. Agregar AuthProvider
Envuelve tu aplicación con el AuthProvider en app/layout.tsx:
import { AuthProvider } from "@fcfmclub/auth";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="es">
<body>
<AuthProvider
config={{
apiUrl: process.env.NEXT_PUBLIC_API_URL || "https://alpha.fcfm.club/api",
clientId: process.env.NEXT_PUBLIC_OAUTH_CLIENT_ID,
}}
>
{children}
</AuthProvider>
</body>
</html>
);
}4. (Opcional) Página de error
Crea app/auth/error/page.tsx:
"use client";
import { useSearchParams } from "next/navigation";
export default function AuthErrorPage() {
const searchParams = useSearchParams();
const message = searchParams.get("message") || "Error de autenticación";
return (
<div className="flex items-center justify-center min-h-screen">
<div className="text-center">
<h1 className="text-2xl font-bold mb-4">Error de Autenticación</h1>
<p className="text-gray-600 mb-6">{message}</p>
<a href="/" className="text-blue-600 hover:underline">
Volver al inicio
</a>
</div>
</div>
);
}Uso
Hook useAuth
"use client";
import { useAuth } from "@fcfmclub/auth";
export default function ProfilePage() {
const { user, loading, isAuthenticated, loginWithGoogle, logout } = useAuth();
if (loading) {
return <div>Cargando...</div>;
}
if (!isAuthenticated) {
return (
<div>
<h1>No estás autenticado</h1>
<button onClick={loginWithGoogle}>
Iniciar sesión con Google
</button>
</div>
);
}
return (
<div>
<h1>Bienvenido, {user?.name}</h1>
<p>Email: {user?.email}</p>
<p>Batería: {user?.battery.percentage}%</p>
<button onClick={logout}>Cerrar sesión</button>
</div>
);
}Rutas disponibles
El paquete maneja automáticamente las siguientes rutas:
/auth/signin- Inicia el flujo de autenticación OAuth/auth/callback- Callback de OAuth (intercambia código por token)/auth/logout- Cierra la sesión
Verificar autenticación del lado del servidor
import { cookies } from "next/headers";
export default async function ServerPage() {
const cookieStore = await cookies();
const authToken = cookieStore.get("auth_token");
const userInfo = cookieStore.get("user_info");
if (!authToken) {
return <div>No autenticado</div>;
}
const user = JSON.parse(userInfo?.value || "{}");
return <div>Hola, {user.name}</div>;
}API
FCFMAuthConfig
interface FCFMAuthConfig {
/** URL base de la API */
apiUrl?: string;
/** Client ID (default: process.env.OAUTH_CLIENT_ID) */
clientId?: string;
/** Client Secret (default: process.env.OAUTH_CLIENT_SECRET) */
clientSecret?: string;
/** Ruta de redirección después del login (default: "/") */
successRedirect?: string;
/** Ruta de página de error (default: "/auth/error") */
errorRedirect?: string;
/** Ambiente (default: process.env.NODE_ENV) */
environment?: "production" | "development";
}AuthContextType
interface AuthContextType {
user: UserWithBattery | null;
loading: boolean;
login: (email: string, password: string) => Promise<void>;
loginWithGoogle: () => void;
logout: () => Promise<void>;
refreshUser: () => void;
isAuthenticated: boolean;
}Cookies
El paquete utiliza las siguientes cookies:
auth_token- Token de acceso (no HTTP-only para permitir uso en cliente)refresh_token- Token de refresco (HTTP-only, seguro)user_info- Información del usuario (no HTTP-only)
Seguridad
- En producción, todas las cookies se marcan como
secure(solo HTTPS) - El
client_secretnunca se expone al cliente - El intercambio de código por token se hace del lado del servidor
- Los tokens tienen expiración automática
Licencia
MIT
Autor
FCFM Club
