@betabridge/azure-ad-auth-nextjs
v3.1.0
Published
Simple Azure AD Authentication Library for Next.js - Plug and Play Solution
Maintainers
Readme
Azure AD Authentication for Next.js
🚀 Simple and powerful Azure Active Directory authentication for Next.js - Plug and play solution!
Overview
A comprehensive Azure AD authentication library for Next.js applications. No B2C complexity - just simple, straightforward Azure AD integration with full SSR support.
Features
✅ Simple Azure AD Integration - Works with regular Azure Active Directory
✅ Next.js Optimized - Full SSR support and App Router compatibility
✅ Multi-tenant Support - Support for 'common', 'organizations', or specific tenants
✅ TypeScript Ready - Full TypeScript support with type definitions
✅ React Hooks - Modern React hooks API
✅ Pre-built Components - Ready-to-use UI components
✅ Middleware Support - Built-in Next.js middleware for route protection
✅ API Routes - Ready-to-use API routes for authentication
✅ Secure - Built on Microsoft MSAL
✅ Zero Config - Sensible defaults, minimal setup
Installation
npm install @betabridge/azure-ad-auth-nextjs
# or
yarn add @betabridge/azure-ad-auth-nextjsQuick Start
1. Basic Setup
// pages/_app.tsx
import { AuthProvider } from '@betabridge/azure-ad-auth-nextjs';
const config = {
tenantId: 'your-tenant-id',
clientId: 'your-client-id',
redirectUri: 'http://localhost:3000',
postLogoutRedirectUri: 'http://localhost:3000',
scope: ['openid', 'profile', 'email', 'User.Read']
};
function MyApp({ Component, pageProps }) {
return (
<AuthProvider config={config}>
<Component {...pageProps} />
</AuthProvider>
);
}
export default MyApp;2. Using in Pages
// pages/dashboard.tsx
import { useAuth, LoginButton, LogoutButton, UserProfile } from '@betabridge/azure-ad-auth-nextjs';
export default function Dashboard() {
const { isAuthenticated, user, login, logout } = useAuth();
return (
<div>
{isAuthenticated ? (
<>
<h1>Welcome {user?.name}!</h1>
<UserProfile />
<LogoutButton />
</>
) : (
<LoginButton />
)}
</div>
);
}3. Using with App Router (Next.js 13+)
// app/layout.tsx
import { AuthProvider } from '@betabridge/azure-ad-auth-nextjs';
const config = {
tenantId: 'your-tenant-id',
clientId: 'your-client-id',
redirectUri: 'http://localhost:3000',
postLogoutRedirectUri: 'http://localhost:3000',
scope: ['openid', 'profile', 'email', 'User.Read']
};
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<AuthProvider config={config}>
{children}
</AuthProvider>
</body>
</html>
)
}Configuration
AzureADConfig
interface AzureADConfig {
// Required
tenantId: string; // Your tenant ID or 'common'/'organizations'
clientId: string; // Application (client) ID
redirectUri: string; // Where to redirect after login
postLogoutRedirectUri: string; // Where to redirect after logout
scope: string[]; // OAuth scopes
// Optional
authority?: string; // Custom authority URL
cacheLocation?: 'localStorage' | 'sessionStorage';
storeAuthStateInCookie?: boolean;
loginHint?: string;
domainHint?: string;
prompt?: 'login' | 'select_account' | 'consent' | 'none';
// Next.js specific
ssr?: boolean; // Enable SSR support
loginRedirectPath?: string; // Custom redirect path after login
logoutRedirectPath?: string; // Custom redirect path after logout
}Environment Variables
Create a .env.local file:
AZURE_AD_TENANT_ID=your-tenant-id
AZURE_AD_CLIENT_ID=your-client-id
AZURE_AD_REDIRECT_URI=http://localhost:3000
AZURE_AD_POST_LOGOUT_REDIRECT_URI=http://localhost:3000API Reference
Hooks
useAuth()
Main authentication hook.
const {
isAuthenticated, // boolean
user, // User object or null
login, // () => Promise<void>
logout, // () => Promise<void>
loading, // boolean
error, // string or null
getAccessToken, // (scopes?: string[]) => Promise<string | null>
refreshToken, // () => Promise<void>
clearError // () => void
} = useAuth();useProtectedRoute()
For route protection.
const { isAllowed, isLoading, shouldRedirect } = useProtectedRoute({
redirectTo: '/login',
redirectImmediately: true
});Components
<AuthProvider>
Wraps your app to provide authentication context.
<AuthProvider config={azureADConfig}>
{children}
</AuthProvider><LoginButton>
Pre-styled login button.
<LoginButton
text="Sign In with Azure AD"
className="custom-class"
onClick={handleCustomLogin}
/><LogoutButton>
Pre-styled logout button.
<LogoutButton
text="Sign Out"
className="custom-class"
/><UserProfile>
Displays user information.
<UserProfile
showEmail={true}
showName={true}
showUserId={false}
/><ProtectedRoute>
Protects routes requiring authentication.
<ProtectedRoute
redirectTo="/login"
fallback={<div>Loading...</div>}
>
<Dashboard />
</ProtectedRoute>Route Protection
Using Middleware
Create middleware.ts in your project root:
import { createAuthMiddleware } from '@betabridge/azure-ad-auth-nextjs';
const config = {
azureAD: {
tenantId: process.env.AZURE_AD_TENANT_ID!,
clientId: process.env.AZURE_AD_CLIENT_ID!,
redirectUri: process.env.AZURE_AD_REDIRECT_URI!,
postLogoutRedirectUri: process.env.AZURE_AD_POST_LOGOUT_REDIRECT_URI!,
scope: ['openid', 'profile', 'email', 'User.Read']
},
protectedRoutes: ['/dashboard', '/profile', '/admin'],
publicRoutes: ['/', '/login', '/about'],
loginPath: '/login'
};
export default createAuthMiddleware(config);Using HOC
import { withAuth } from '@betabridge/azure-ad-auth-nextjs';
function Dashboard() {
return <div>Protected content</div>;
}
export default withAuth(Dashboard, {
redirectTo: '/login',
fallback: <div>Loading...</div>
});API Routes
The package includes ready-to-use API routes:
GET /api/auth/login- Initiate loginGET /api/auth/callback- Handle login callbackPOST /api/auth/logout- Handle logout
SSR Support
The library automatically handles server-side rendering:
// This works on both client and server
const { isAuthenticated, user } = useAuth();
// Server-side safe
if (typeof window !== 'undefined') {
// Client-side only code
}Common Configurations
Single Tenant
const config = {
tenantId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
clientId: 'your-client-id',
redirectUri: 'http://localhost:3000',
postLogoutRedirectUri: 'http://localhost:3000',
scope: ['openid', 'profile', 'email', 'User.Read']
};Multi-Tenant
const config = {
tenantId: 'common', // Anyone with Microsoft account
clientId: 'your-client-id',
redirectUri: 'http://localhost:3000',
postLogoutRedirectUri: 'http://localhost:3000',
scope: ['openid', 'profile', 'email', 'User.Read']
};Organizations Only
const config = {
tenantId: 'organizations', // Work/school accounts only
clientId: 'your-client-id',
redirectUri: 'http://localhost:3000',
postLogoutRedirectUri: 'http://localhost:3000',
scope: ['openid', 'profile', 'email', 'User.Read']
};Azure Portal Setup
Step 1: Register Application
- Go to Azure Portal
- Navigate to Azure Active Directory
- Select App registrations → New registration
Step 2: Configure Registration
- Name: Your application name
- Supported account types: Choose based on your needs
- Redirect URI:
- Type: Single-page application (SPA)
- URI:
http://localhost:3000(for development)
Step 3: Get Credentials
From the app Overview page:
- Application (client) ID → use as
clientId - Directory (tenant) ID → use as
tenantId
Step 4: Configure Authentication
- Go to Authentication section
- Add redirect URIs for all environments
- Enable ID tokens and Access tokens
Step 5: Set API Permissions
- Go to API permissions
- Add Microsoft Graph → Delegated permissions
- Add:
User.Read,openid,profile,email - Grant admin consent if required
Examples
Complete App with Pages Router
// pages/_app.tsx
import { AuthProvider } from '@betabridge/azure-ad-auth-nextjs';
const config = {
tenantId: process.env.AZURE_AD_TENANT_ID!,
clientId: process.env.AZURE_AD_CLIENT_ID!,
redirectUri: process.env.AZURE_AD_REDIRECT_URI!,
postLogoutRedirectUri: process.env.AZURE_AD_POST_LOGOUT_REDIRECT_URI!,
scope: ['openid', 'profile', 'email', 'User.Read']
};
export default function App({ Component, pageProps }) {
return (
<AuthProvider config={config}>
<Component {...pageProps} />
</AuthProvider>
);
}
// pages/dashboard.tsx
import { useAuth, ProtectedRoute } from '@betabridge/azure-ad-auth-nextjs';
export default function Dashboard() {
const { user, logout } = useAuth();
return (
<ProtectedRoute>
<div>
<h1>Dashboard</h1>
<p>Welcome, {user?.name}!</p>
<button onClick={() => logout()}>Logout</button>
</div>
</ProtectedRoute>
);
}Complete App with App Router
// app/layout.tsx
import { AuthProvider } from '@betabridge/azure-ad-auth-nextjs';
const config = {
tenantId: process.env.AZURE_AD_TENANT_ID!,
clientId: process.env.AZURE_AD_CLIENT_ID!,
redirectUri: process.env.AZURE_AD_REDIRECT_URI!,
postLogoutRedirectUri: process.env.AZURE_AD_POST_LOGOUT_REDIRECT_URI!,
scope: ['openid', 'profile', 'email', 'User.Read']
};
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<AuthProvider config={config}>
{children}
</AuthProvider>
</body>
</html>
)
}
// app/dashboard/page.tsx
'use client';
import { useAuth, ProtectedRoute } from '@betabridge/azure-ad-auth-nextjs';
export default function Dashboard() {
const { user, logout } = useAuth();
return (
<ProtectedRoute>
<div>
<h1>Dashboard</h1>
<p>Welcome, {user?.name}!</p>
<button onClick={() => logout()}>Logout</button>
</div>
</ProtectedRoute>
);
}TypeScript Support
Full TypeScript support with comprehensive type definitions:
import type {
AzureADConfig,
User,
AuthState,
LoginOptions
} from '@betabridge/azure-ad-auth-nextjs';Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Requirements
- Next.js >= 12.0.0
- React >= 16.8.0
- react-dom >= 16.8.0
License
MIT
Support
- 📖 Documentation: See this file
- 🐛 Issues: Report on GitHub
- 💬 Questions: Open a discussion
Links
Made with ❤️ for the Next.js community
