The Crossmint Server SDK automatically manages user sessions by validating JWT tokens and refreshing them when they expire.
How Session Validation Works
When you call getSession(), the SDK performs the following steps:
Retrieve authentication material
The SDK extracts the JWT and refresh token from cookies or the provided request object.
Validate the JWT
The SDK verifies the JWT signature and checks if it’s expired.
Refresh if needed
If the JWT is expired or invalid, the SDK automatically uses the refresh token to obtain a new JWT.
Store updated tokens
If a response object is provided, the SDK stores the refreshed tokens in cookies.
Source: CrossmintAuthServer.ts:166
Session Validation
Basic Session Validation
The getSession() method automatically validates and refreshes sessions:
const { jwt , userId , refreshToken } = await crossmintAuth . getSession ( request , response );
The returned object contains:
jwt - The validated (or refreshed) JWT token
userId - The user’s unique identifier
refreshToken - The refresh token object with secret and expiresAt
Validation Without Auto-Refresh
If you want to validate a JWT without automatic refresh, use verifyCrossmintJwt():
try {
const decodedToken = await crossmintAuth . verifyCrossmintJwt ( jwt );
const userId = decodedToken . sub ;
// JWT is valid
} catch ( error ) {
// JWT is invalid or expired
}
Token Refresh
Automatic Token Refresh
The SDK automatically refreshes expired tokens when calling getSession(). No additional code is required:
// Automatically refreshes if JWT is expired
const { jwt , userId } = await crossmintAuth . getSession ( request , response );
Manual Token Refresh
You can manually refresh tokens using the handleCustomRefresh() method. This is useful for setting up custom refresh endpoints.
Next.js (Fetch API)
Express (Node.js API)
export async function POST ( request : NextRequest ) {
return await crossmintAuth . handleCustomRefresh ( request );
}
Source: README.md:89
For Fetch API environments, handleCustomRefresh() returns a Response object. For Node.js environments, you must provide the response object and call res.end() after the method completes.
Logout
The logout() method clears authentication material from cookies and optionally calls the Crossmint logout endpoint.
Logout in Fetch API Environments
export async function POST ( request : NextRequest ) {
return await crossmintAuth . logout ( request );
}
Source: README.md:120
Logout in Node.js API Environments
app . post ( "/api/logout" , async ( req , res ) => {
await crossmintAuth . logout ( req , res );
res . end ();
});
Source: README.md:126
What Happens During Logout
Call logout endpoint
The SDK calls the Crossmint logout endpoint to invalidate the refresh token (if possible).
Clear cookies
Authentication cookies are cleared by setting them to empty values with past expiration dates.
Return response
A response object is returned with the cleared cookies.
Source: CrossmintAuthServer.ts:141
Cookie Names
The SDK uses the following cookie names by default:
crossmint-session - Stores the JWT token (not HttpOnly, accessible to the client SDK)
crossmint-refresh-token - Stores the refresh token (can be HttpOnly for security)
Session Error Handling
When session validation or refresh fails, the SDK:
Throws a CrossmintAuthenticationError
Automatically clears cookies if a response object is provided
Logs the error to the console
try {
const { jwt , userId } = await crossmintAuth . getSession ( request , response );
} catch ( error ) {
// Cookies are automatically cleared
// Redirect user to login page
return redirect ( "/login" );
}
Complete Example: Protected Route
Next.js Middleware
Express Middleware
import { NextResponse } from "next/server" ;
import type { NextRequest } from "next/server" ;
import { createCrossmint , CrossmintAuth } from "@crossmint/server-sdk" ;
const crossmint = createCrossmint ({
apiKey: process . env . SERVER_CROSSMINT_API_KEY || "" ,
});
const crossmintAuth = CrossmintAuth . from ( crossmint );
export async function middleware ( request : NextRequest ) {
try {
const jwt = request . cookies . get ( "crossmint-session" )?. value ;
const refreshToken = request . cookies . get ( "crossmint-refresh-token" )?. value ;
const { userId } = await crossmintAuth . getSession ({
jwt ,
refreshToken ,
});
// User is authenticated, continue
return NextResponse . next ();
} catch ( error ) {
// Redirect to login if authentication fails
return NextResponse . redirect ( new URL ( "/login" , request . url ));
}
}
export const config = {
matcher: "/dashboard/:path*" ,
};
Next Steps
Custom Refresh Routes Set up custom refresh routes for enhanced security with HttpOnly cookies