CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-aws-amplify--auth

Authentication category of AWS Amplify providing APIs and building blocks for creating authentication experiences with Amazon Cognito

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

server-side-apis.mddocs/

Server-Side APIs

Dedicated server-side authentication APIs for SSR applications, backend services, and Next.js applications.

Server-Side Overview

The server-side APIs provide authentication functionality specifically designed for server environments. These APIs work with server-side sessions and cookies rather than client-side token storage.

Import Paths

// Main server export
import { getCurrentUser, fetchUserAttributes } from "@aws-amplify/auth/server";

// All server-side functionality
import * as AmplifyServer from "@aws-amplify/auth/server";

Get Current User (Server)

Retrieve the currently authenticated user in a server environment.

function getCurrentUser(): Promise<AuthUser>;

Usage Example

import { getCurrentUser } from "@aws-amplify/auth/server";

// In a Next.js API route or server component
export async function getServerSideProps(context) {
  try {
    const user = await getCurrentUser();
    
    return {
      props: {
        user: {
          username: user.username,
          userId: user.userId
        }
      }
    };
  } catch (error) {
    // User not authenticated
    return {
      redirect: {
        destination: '/login',
        permanent: false
      }
    };
  }
}

// In Express.js middleware
app.use(async (req, res, next) => {
  try {
    const user = await getCurrentUser();
    req.user = user;
    next();
  } catch (error) {
    res.status(401).json({ error: 'Unauthorized' });
  }
});

Fetch User Attributes (Server)

Get user attributes in a server environment.

function fetchUserAttributes(): Promise<FetchUserAttributesOutput>;

type FetchUserAttributesOutput = Record<UserAttributeKey, string>;

Usage Example

import { fetchUserAttributes } from "@aws-amplify/auth/server";

// In a Next.js API route
export default async function handler(req, res) {
  try {
    const attributes = await fetchUserAttributes();
    
    res.json({
      profile: {
        email: attributes.email,
        name: attributes.name,
        phoneNumber: attributes.phone_number
      }
    });
  } catch (error) {
    res.status(401).json({ error: 'User not authenticated' });
  }
}

// In server-side component
async function UserProfile() {
  try {
    const attributes = await fetchUserAttributes();
    
    return (
      <div>
        <h1>Welcome, {attributes.name}</h1>
        <p>Email: {attributes.email}</p>
      </div>
    );
  } catch (error) {
    return <div>Please sign in</div>;
  }
}

Next.js Integration

Complete integration with Next.js applications:

App Router (Next.js 13+)

// app/lib/auth.ts
import { getCurrentUser, fetchUserAttributes } from "@aws-amplify/auth/server";

export async function getServerUser() {
  try {
    const user = await getCurrentUser();
    const attributes = await fetchUserAttributes();
    
    return {
      user,
      attributes,
      isAuthenticated: true
    };
  } catch (error) {
    return {
      user: null,
      attributes: null,
      isAuthenticated: false
    };
  }
}

// app/dashboard/page.tsx
import { getServerUser } from '../lib/auth';
import { redirect } from 'next/navigation';

export default async function Dashboard() {
  const { user, attributes, isAuthenticated } = await getServerUser();
  
  if (!isAuthenticated) {
    redirect('/login');
  }
  
  return (
    <div>
      <h1>Dashboard</h1>
      <p>Welcome, {attributes?.name}</p>
      <p>User ID: {user?.userId}</p>
    </div>
  );
}

// app/api/profile/route.ts
import { fetchUserAttributes } from "@aws-amplify/auth/server";
import { NextResponse } from 'next/server';

export async function GET() {
  try {
    const attributes = await fetchUserAttributes();
    
    return NextResponse.json({
      success: true,
      profile: attributes
    });
  } catch (error) {
    return NextResponse.json(
      { success: false, error: 'Unauthorized' },
      { status: 401 }
    );
  }
}

Pages Router (Next.js 12 and earlier)

// lib/auth.js
import { getCurrentUser, fetchUserAttributes } from "@aws-amplify/auth/server";

export async function getServerSideUser(context) {
  try {
    const user = await getCurrentUser();
    const attributes = await fetchUserAttributes();
    
    return { user, attributes };
  } catch (error) {
    return { user: null, attributes: null };
  }
}

// pages/dashboard.js
import { getServerSideUser } from '../lib/auth';

export async function getServerSideProps(context) {
  const { user, attributes } = await getServerSideUser(context);
  
  if (!user) {
    return {
      redirect: {
        destination: '/login',
        permanent: false
      }
    };
  }
  
  return {
    props: {
      user: {
        username: user.username,
        userId: user.userId
      },
      profile: attributes
    }
  };
}

export default function Dashboard({ user, profile }) {
  return (
    <div>
      <h1>Welcome, {profile.name}</h1>
      <p>User ID: {user.userId}</p>
    </div>
  );
}

// pages/api/me.js
import { getCurrentUser, fetchUserAttributes } from "@aws-amplify/auth/server";

export default async function handler(req, res) {
  try {
    const user = await getCurrentUser();
    const attributes = await fetchUserAttributes();
    
    res.json({
      user: {
        username: user.username,
        userId: user.userId
      },
      attributes
    });
  } catch (error) {
    res.status(401).json({ error: 'Unauthorized' });
  }
}

Express.js Integration

Using server-side APIs with Express.js:

import express from 'express';
import { getCurrentUser, fetchUserAttributes } from "@aws-amplify/auth/server";

const app = express();

// Authentication middleware
async function requireAuth(req, res, next) {
  try {
    const user = await getCurrentUser();
    req.user = user;
    next();
  } catch (error) {
    res.status(401).json({ error: 'Authentication required' });
  }
}

// Protected route
app.get('/api/profile', requireAuth, async (req, res) => {
  try {
    const attributes = await fetchUserAttributes();
    
    res.json({
      user: req.user,
      profile: attributes
    });
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch profile' });
  }
});

// User info endpoint
app.get('/api/user', async (req, res) => {
  try {
    const user = await getCurrentUser();
    const attributes = await fetchUserAttributes();
    
    res.json({
      authenticated: true,
      user: {
        username: user.username,
        userId: user.userId,
        email: attributes.email,
        name: attributes.name
      }
    });
  } catch (error) {
    res.json({
      authenticated: false,
      user: null
    });
  }
});

app.listen(3000);

Server-Side Session Management

Managing authentication state on the server:

import { getCurrentUser, fetchUserAttributes } from "@aws-amplify/auth/server";

class ServerAuthManager {
  async getAuthenticatedUser() {
    try {
      const user = await getCurrentUser();
      const attributes = await fetchUserAttributes();
      
      return {
        isAuthenticated: true,
        user: {
          username: user.username,
          userId: user.userId,
          signInDetails: user.signInDetails
        },
        profile: attributes
      };
    } catch (error) {
      return {
        isAuthenticated: false,
        user: null,
        profile: null,
        error: error.message
      };
    }
  }
  
  async requireAuthentication() {
    const result = await this.getAuthenticatedUser();
    
    if (!result.isAuthenticated) {
      throw new Error('Authentication required');
    }
    
    return result;
  }
  
  async getUserId(): Promise<string | null> {
    try {
      const user = await getCurrentUser();
      return user.userId;
    } catch (error) {
      return null;
    }
  }
  
  async getUserAttribute(attributeKey: UserAttributeKey): Promise<string | null> {
    try {
      const attributes = await fetchUserAttributes();
      return attributes[attributeKey] || null;
    } catch (error) {
      return null;
    }
  }
}

// Usage
const authManager = new ServerAuthManager();

// In API handler
export async function apiHandler(req, res) {
  try {
    const { user, profile } = await authManager.requireAuthentication();
    
    // Process authenticated request
    res.json({ user, profile });
  } catch (error) {
    res.status(401).json({ error: 'Unauthorized' });
  }
}

Cookie and Session Handling

Server-side APIs work with HTTP cookies and server sessions:

// Cookie configuration for server-side auth
const cookieConfig = {
  httpOnly: true,
  secure: process.env.NODE_ENV === 'production',
  sameSite: 'strict',
  maxAge: 24 * 60 * 60 * 1000 // 24 hours
};

// Express middleware for cookie handling
app.use(cookieParser());

// Custom session validation
async function validateSession(req, res, next) {
  const sessionToken = req.cookies['amplify-session'];
  
  if (!sessionToken) {
    return res.status(401).json({ error: 'No session token' });
  }
  
  try {
    // Amplify handles session validation internally
    const user = await getCurrentUser();
    req.user = user;
    next();
  } catch (error) {
    // Clear invalid session cookie
    res.clearCookie('amplify-session');
    res.status(401).json({ error: 'Invalid session' });
  }
}

Error Handling

Handle server-side authentication errors:

import { getCurrentUser, AuthError } from "@aws-amplify/auth/server";

async function handleServerAuth(req, res) {
  try {
    const user = await getCurrentUser();
    return { success: true, user };
  } catch (error) {
    if (error instanceof AuthError) {
      switch (error.name) {
        case 'NotAuthorizedException':
          return { success: false, error: 'User not authenticated', statusCode: 401 };
        case 'UserNotConfirmedException':
          return { success: false, error: 'User not confirmed', statusCode: 403 };
        case 'TokenExpiredException':
          return { success: false, error: 'Session expired', statusCode: 401 };
        case 'NetworkError':
          return { success: false, error: 'Network error', statusCode: 503 };
        default:
          return { success: false, error: 'Authentication error', statusCode: 500 };
      }
    }
    
    return { success: false, error: 'Unknown error', statusCode: 500 };
  }
}

// Usage in API route
export default async function handler(req, res) {
  const { success, user, error, statusCode } = await handleServerAuth(req, res);
  
  if (!success) {
    return res.status(statusCode).json({ error });
  }
  
  // Continue with authenticated request
  res.json({ user });
}

Best Practices

Performance

  • Cache user data appropriately in server memory or Redis
  • Use connection pooling for database connections
  • Implement proper session timeout handling
  • Minimize API calls by batching operations

Security

  • Always validate sessions on the server side
  • Use secure cookies with appropriate flags
  • Implement proper CSRF protection
  • Validate user permissions for each request

Error Handling

  • Provide consistent error responses
  • Log authentication failures for monitoring
  • Handle token expiration gracefully
  • Implement proper retry logic for network errors

Monitoring

  • Track authentication success/failure rates
  • Monitor session duration and usage patterns
  • Set up alerts for authentication anomalies
  • Log security-relevant events

docs

authentication-lifecycle.md

device-management.md

index.md

multi-factor-authentication.md

oauth-social-authentication.md

password-management.md

server-side-apis.md

session-management.md

user-management.md

webauthn-credentials.md

tile.json