Skip to content

Latest commit

 

History

History
434 lines (363 loc) · 10.2 KB

File metadata and controls

434 lines (363 loc) · 10.2 KB

Authentication 🔐

Authentication and authorization solutions for modern web applications.

Firebase Auth

Description: Google's mobile and web authentication service with comprehensive security features and easy integration.

Key Features:

  • Multiple authentication providers
  • User management
  • Security rules
  • Real-time database integration
  • Cloud functions support
  • Analytics integration
  • Easy setup and configuration

Installation:

npm install firebase

Configuration:

// firebase.js
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';

const firebaseConfig = {
  apiKey: "your-api-key",
  authDomain: "your-project.firebaseapp.com",
  projectId: "your-project-id",
  storageBucket: "your-project.appspot.com",
  messagingSenderId: "123456789",
  appId: "your-app-id"
};

const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);

Basic Usage:

import { useState, useEffect } from 'react';
import {
  signInWithEmailAndPassword,
  createUserWithEmailAndPassword,
  signOut,
  onAuthStateChanged,
  GoogleAuthProvider,
  signInWithPopup
} from 'firebase/auth';
import { auth } from './firebase';

function AuthApp() {
  const [user, setUser] = useState(null);
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      setUser(user);
      setLoading(false);
    });

    return () => unsubscribe();
  }, []);

  const handleSignUp = async (e) => {
    e.preventDefault();
    try {
      await createUserWithEmailAndPassword(auth, email, password);
    } catch (error) {
      console.error('Sign up error:', error);
    }
  };

  const handleSignIn = async (e) => {
    e.preventDefault();
    try {
      await signInWithEmailAndPassword(auth, email, password);
    } catch (error) {
      console.error('Sign in error:', error);
    }
  };

  const handleGoogleSignIn = async () => {
    try {
      const provider = new GoogleAuthProvider();
      await signInWithPopup(auth, provider);
    } catch (error) {
      console.error('Google sign in error:', error);
    }
  };

  const handleSignOut = async () => {
    try {
      await signOut(auth);
    } catch (error) {
      console.error('Sign out error:', error);
    }
  };

  if (loading) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      {user ? (
        <div>
          <h2>Welcome, {user.email}</h2>
          <button onClick={handleSignOut}>Sign Out</button>
        </div>
      ) : (
        <div>
          <form onSubmit={handleSignUp}>
            <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="Email"
            />
            <input
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              placeholder="Password"
            />
            <button type="submit">Sign Up</button>
          </form>
          
          <button onClick={handleSignIn}>Sign In</button>
          <button onClick={handleGoogleSignIn}>Sign in with Google</button>
        </div>
      )}
    </div>
  );
}

Use Cases: Web applications, mobile apps, real-time applications, rapid prototyping

NextAuth.js

Description: Authentication for Next.js with built-in support for multiple providers and session management.

Key Features:

  • Built for Next.js
  • Multiple OAuth providers
  • Database sessions
  • JWT support
  • TypeScript support
  • Middleware support
  • Custom pages

Installation:

npm install next-auth

Configuration (pages/api/auth/[...nextauth].js):

import NextAuth from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import CredentialsProvider from 'next-auth/providers/credentials';

export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    CredentialsProvider({
      name: 'credentials',
      credentials: {
        email: { label: 'Email', type: 'email' },
        password: { label: 'Password', type: 'password' }
      },
      async authorize(credentials) {
        // Add your own authentication logic here
        const user = await authenticateUser(credentials.email, credentials.password);
        if (user) {
          return { id: user.id, email: user.email, name: user.name };
        }
        return null;
      }
    })
  ],
  pages: {
    signIn: '/auth/signin',
    error: '/auth/error',
  },
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.id = user.id;
      }
      return token;
    },
    async session({ session, token }) {
      session.user.id = token.id;
      return session;
    }
  }
});

Basic Usage:

import { useSession, signIn, signOut } from 'next-auth/react';
import { SessionProvider } from 'next-auth/react';

function MyApp({ Component, pageProps }) {
  return (
    <SessionProvider>
      <Component {...pageProps} />
    </SessionProvider>
  );
}

function HomePage() {
  const { data: session, status } = useSession();

  if (status === 'loading') {
    return <div>Loading...</div>;
  }

  if (session) {
    return (
      <div>
        <h1>Welcome, {session.user.email}</h1>
        <button onClick={() => signOut()}>Sign Out</button>
      </div>
    );
  }

  return (
    <div>
      <h1>Please sign in</h1>
      <button onClick={() => signIn('google')}>Sign in with Google</button>
      <button onClick={() => signIn()}>Sign in</button>
    </div>
  );
}

// Middleware protection
import { withAuth } from 'next-auth/middleware';

export default withAuth({
  pages: {
    signIn: '/auth/signin',
  },
});

export const config = {
  matcher: ['/dashboard/:path*', '/admin/:path*']
};

Use Cases: Next.js applications, server-side rendering, API routes

Auth0

Description: Identity and access management platform with comprehensive authentication and authorization features.

Key Features:

  • Universal login
  • Social connections
  • Multi-factor authentication
  • User management dashboard
  • API authorization
  • Branding customization
  • Analytics and monitoring

Installation:

npm install @auth0/nextjs-auth0

Configuration (.env.local):

AUTH0_SECRET='your-secret'
AUTH0_BASE_URL='http://localhost:3000'
AUTH0_ISSUER_BASE_URL='https://your-domain.auth0.com'
AUTH0_CLIENT_ID='your-client-id'
AUTH0_CLIENT_SECRET='your-client-secret'

Setup (pages/api/auth/[...auth0].js):

import { handleAuth } from '@auth0/nextjs-auth0';

export default handleAuth();

Basic Usage:

import { UserProvider, useUser } from '@auth0/nextjs-auth0/client';
import { getSession } from '@auth0/nextjs-auth0';

function MyApp({ Component, pageProps }) {
  return (
    <UserProvider>
      <Component {...pageProps} />
    </UserProvider>
  );
}

function HomePage() {
  const { user, error, isLoading } = useUser();

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>{error.message}</div>;

  if (user) {
    return (
      <div>
        <h1>Welcome, {user.name}</h1>
        <p>Email: {user.email}</p>
        <a href="/api/auth/logout">Logout</a>
      </div>
    );
  }

  return (
    <div>
      <h1>Please login</h1>
      <a href="/api/auth/login">Login</a>
    </div>
  );
}

// Server-side authentication
export async function getServerSideProps(context) {
  const session = await getSession(context.req, context.res);

  if (!session) {
    return {
      redirect: {
        destination: '/api/auth/login',
        permanent: false,
      },
    };
  }

  return {
    props: {
      user: session.user,
    },
  };
}

Use Cases: Enterprise applications, complex authentication requirements, compliance needs

Comparison Table

Solution Setup Complexity Customization Enterprise Features Use Case
Firebase Auth Low Medium Basic Rapid development, real-time apps
NextAuth.js Medium High Medium Next.js applications
Auth0 Medium High Comprehensive Enterprise applications

When to Use Each

  • Firebase Auth: When you need quick setup with real-time features and Google ecosystem integration
  • NextAuth.js: When building Next.js applications with custom authentication requirements
  • Auth0: When you need enterprise-grade authentication with comprehensive features and compliance

Best Practices

  1. Security: Always validate tokens and implement proper session management
  2. Environment Variables: Store sensitive credentials in environment variables
  3. Error Handling: Implement proper error handling for authentication flows
  4. User Experience: Provide clear feedback during authentication processes
  5. Testing: Mock authentication in tests and use proper test accounts
  6. Monitoring: Implement logging and monitoring for authentication events
  7. Compliance: Ensure compliance with data protection regulations (GDPR, CCPA)
  8. Multi-Factor: Enable multi-factor authentication for enhanced security

Advanced Patterns

Custom Hook for Authentication

import { useAuth } from './useAuth';

function useRequireAuth() {
  const { user, loading } = useAuth();
  
  useEffect(() => {
    if (!loading && !user) {
      // Redirect to login page
      window.location.href = '/login';
    }
  }, [user, loading]);
  
  return { user, loading };
}

Role-Based Access Control

function usePermissions() {
  const { user } = useAuth();
  
  const hasPermission = (permission) => {
    return user?.permissions?.includes(permission);
  };
  
  const hasRole = (role) => {
    return user?.roles?.includes(role);
  };
  
  return { hasPermission, hasRole };
}

Protected Routes

function ProtectedRoute({ children, requiredRole }) {
  const { user, loading } = useAuth();
  const { hasRole } = usePermissions();
  
  if (loading) return <div>Loading...</div>;
  if (!user) return <Navigate to="/login" />;
  if (requiredRole && !hasRole(requiredRole)) {
    return <Navigate to="/unauthorized" />;
  }
  
  return children;
}