Dedicated server-side authentication APIs for SSR applications, backend services, and Next.js applications.
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.
// Main server export
import { getCurrentUser, fetchUserAttributes } from "@aws-amplify/auth/server";
// All server-side functionality
import * as AmplifyServer from "@aws-amplify/auth/server";Retrieve the currently authenticated user in a server environment.
function getCurrentUser(): Promise<AuthUser>;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' });
}
});Get user attributes in a server environment.
function fetchUserAttributes(): Promise<FetchUserAttributesOutput>;
type FetchUserAttributesOutput = Record<UserAttributeKey, string>;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>;
}
}Complete integration with Next.js applications:
// 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 }
);
}
}// 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' });
}
}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);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' });
}
}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' });
}
}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 });
}