opensora-uaa-nextjs
v1.0.1
Published
Universal Authentication & Authorization SDK for Next.js
Maintainers
Readme
@opensora/uaa-nextjs
Universal Authentication & Authorization SDK for Next.js with React Hooks.
Installation
npm install @opensora/uaa-nextjsQuick Start
1. Wrap your app with UAAProvider
// app/layout.tsx or app/providers.tsx
'use client';
import { UAAProvider } from '@opensora/uaa-nextjs';
export default function RootLayout({ children }) {
return (
<html>
<body>
<UAAProvider projectId="your-project-id">
{children}
</UAAProvider>
</body>
</html>
);
}2. Use the useUAA hook
// app/page.tsx
'use client';
import { useUAA } from '@opensora/uaa-nextjs';
export default function HomePage() {
const { user, isAuthenticated, isLoading, logout } = useUAA();
if (isLoading) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return <div>Please login</div>;
}
return (
<div>
<h1>Welcome, {user.name || user.email}!</h1>
<button onClick={logout}>Logout</button>
</div>
);
}Google Sign In
Setup
// app/login/page.tsx
'use client';
import { useUAA } from '@opensora/uaa-nextjs';
import { useEffect } from 'react';
export default function LoginPage() {
const { loginWithGoogle } = useUAA();
useEffect(() => {
// Load Google SDK
const script = document.createElement('script');
script.src = 'https://accounts.google.com/gsi/client';
script.async = true;
script.defer = true;
document.body.appendChild(script);
// Initialize Google Sign In
script.onload = () => {
window.google.accounts.id.initialize({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
callback: handleGoogleCallback,
});
window.google.accounts.id.renderButton(
document.getElementById('google-signin-button'),
{ theme: 'outline', size: 'large' }
);
};
return () => {
document.body.removeChild(script);
};
}, []);
const handleGoogleCallback = async (response) => {
try {
await loginWithGoogle(response.credential);
// Redirect or update UI
window.location.href = '/dashboard';
} catch (error) {
console.error('Login failed:', error);
}
};
return (
<div>
<h1>Login</h1>
<div id="google-signin-button"></div>
</div>
);
}Apple Sign In
// app/login/page.tsx
'use client';
import { useUAA } from '@opensora/uaa-nextjs';
import { useEffect } from 'react';
export default function LoginPage() {
const { loginWithApple } = useUAA();
useEffect(() => {
// Load Apple SDK
const script = document.createElement('script');
script.src = 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
script.async = true;
document.body.appendChild(script);
script.onload = () => {
window.AppleID.auth.init({
clientId: 'YOUR_APPLE_CLIENT_ID',
scope: 'name email',
redirectURI: 'https://yourdomain.com/auth/callback',
usePopup: true,
});
};
return () => {
document.body.removeChild(script);
};
}, []);
const handleAppleLogin = async () => {
try {
const data = await window.AppleID.auth.signIn();
await loginWithApple(data.authorization.code, data.authorization.id_token);
window.location.href = '/dashboard';
} catch (error) {
console.error('Login failed:', error);
}
};
return (
<div>
<h1>Login</h1>
<button onClick={handleAppleLogin}>Sign in with Apple</button>
</div>
);
}Protecting Routes with withAuth
// app/dashboard/page.tsx
'use client';
import { withAuth } from '@opensora/uaa-nextjs';
function DashboardPage() {
return <div>Protected Dashboard Content</div>;
}
// Only authenticated users can access
export default withAuth(DashboardPage);Redirect if Already Authenticated
// app/login/page.tsx
'use client';
import { withAuth } from '@opensora/uaa-nextjs';
function LoginPage() {
return <div>Login Form</div>;
}
// Redirect to /dashboard if already logged in
export default withAuth(LoginPage, {
redirectTo: '/dashboard',
redirectIfAuthenticated: true,
});Complete Example
// app/providers.tsx
'use client';
import { UAAProvider } from '@opensora/uaa-nextjs';
export function Providers({ children }) {
return (
<UAAProvider projectId="your-project-id">
{children}
</UAAProvider>
);
}
// app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
// app/page.tsx
'use client';
import { useUAA } from '@opensora/uaa-nextjs';
import Link from 'next/link';
export default function HomePage() {
const { user, isAuthenticated, logout } = useUAA();
return (
<div>
{isAuthenticated ? (
<>
<p>Welcome, {user.email}!</p>
<button onClick={logout}>Logout</button>
<Link href="/dashboard">Dashboard</Link>
</>
) : (
<Link href="/login">Login</Link>
)}
</div>
);
}
// app/dashboard/page.tsx
'use client';
import { withAuth } from '@opensora/uaa-nextjs';
import { useUAA } from '@opensora/uaa-nextjs';
function DashboardPage() {
const { user } = useUAA();
return (
<div>
<h1>Dashboard</h1>
<p>Email: {user.email}</p>
<p>Provider: {user.provider}</p>
</div>
);
}
export default withAuth(DashboardPage);API Reference
UAAProvider
Context provider for authentication state.
Props:
projectId(required): Your project ID from UAAbaseURL(optional): UAA API base URL (default:https://auth.opensora.store/api/v1)
useUAA()
React hook to access authentication state and methods.
Returns:
{
user: User | null;
accessToken: string | null;
refreshToken: string | null;
isLoading: boolean;
isAuthenticated: boolean;
loginWithGoogle: (credential: string) => Promise<void>;
loginWithApple: (code: string, idToken: string) => Promise<void>;
logout: () => Promise<void>;
refreshAuth: () => Promise<void>;
}withAuth(Component, options?)
Higher-order component to protect pages.
Options:
redirectTo(default:/login): Where to redirectredirectIfAuthenticated(default:false): Redirect if user is logged in (for login pages)
TypeScript Support
Full TypeScript support with type definitions included.
import { useUAA, UAAContextValue, User } from '@opensora/uaa-nextjs';Requirements
- Next.js >= 13.0.0
- React >= 18.0.0
License
MIT
