Authentication
Crossmint SDK provides two authentication clients optimized for different environments: client-side and server-side . Both use JWT-based sessions with refresh tokens for secure, persistent authentication.
Client-Side Authentication
The CrossmintAuthClient is designed for browser and client-side environments, handling authentication flows with automatic token management.
Initialization
import { CrossmintAuth } from "@crossmint/client-sdk-auth" ;
import { createCrossmint } from "@crossmint/common-sdk-base" ;
const crossmint = createCrossmint ({
apiKey: "your-client-api-key"
});
const auth = CrossmintAuth . from ( crossmint , {
callbacks: {
onTokenRefresh : ( authMaterial ) => {
console . log ( "Token refreshed" , authMaterial );
},
onLogout : () => {
console . log ( "User logged out" );
}
},
logoutRoute: "/api/auth/logout" // Optional custom logout endpoint
});
Authentication Methods
The client supports multiple authentication flows:
Email OTP
// Send OTP to email
const { emailId } = await auth . sendEmailOtp ( "[email protected] " );
// Verify OTP
const oneTimeSecret = await auth . confirmEmailOtp (
"[email protected] " ,
emailId ,
"123456"
);
// Exchange for session
await auth . handleRefreshAuthMaterial ( oneTimeSecret );
OAuth Providers
// Get OAuth URL
const oauthUrl = await auth . getOAuthUrl ( "google" );
// Redirect user to oauthUrl
window . location . href = oauthUrl ;
// After redirect, exchange code for session
const params = new URLSearchParams ( window . location . search );
const oneTimeSecret = params . get ( "ots" );
await auth . handleRefreshAuthMaterial ( oneTimeSecret );
OAuth providers include: google, twitter, discord, facebook, and more. Ensure the provider is enabled in your Crossmint Console.
Smart Wallet Authentication
// Request signature challenge
const { message } = await auth . signInWithSmartWallet (
walletAddress ,
"evm" // or "solana"
);
// Sign message with wallet
const signature = await wallet . signMessage ( message );
// Authenticate
const { oneTimeSecret } = await auth . authenticateSmartWallet (
walletAddress ,
"evm" ,
signature
);
await auth . handleRefreshAuthMaterial ( oneTimeSecret );
Farcaster
import { useSignIn } from "@farcaster/auth-kit" ;
const farcasterData = useSignIn ();
const oneTimeSecret = await auth . signInWithFarcaster ( farcasterData );
await auth . handleRefreshAuthMaterial ( oneTimeSecret );
Session Management
The client automatically refreshes JWT tokens before expiration and stores them in browser cookies/localStorage.
// Get current user
const user = await auth . getUser ();
console . log ( user . id , user . email );
// Logout
await auth . logout ();
Token Storage
By default, authentication material is stored in cookies:
jwt - Session token (expires after 1 hour)
refreshToken - Long-lived refresh token (expires after 30 days)
You can customize storage with a custom StorageProvider:
const auth = CrossmintAuth . from ( crossmint , {
storageProvider: {
get : async ( key ) => { /* custom get */ },
set : async ( key , value , expiresAt ) => { /* custom set */ },
remove : async ( key ) => { /* custom remove */ }
}
});
Server-Side Authentication
The CrossmintAuthServer is designed for Node.js server environments, providing session validation and token refresh capabilities.
Initialization
import { CrossmintAuthServer } from "@crossmint/server-sdk-auth" ;
import { createCrossmint } from "@crossmint/common-sdk-base" ;
const crossmint = createCrossmint ({
apiKey: "your-server-api-key"
});
const authServer = CrossmintAuthServer . from ( crossmint , {
cookieOptions: {
secure: true ,
httpOnly: true ,
sameSite: "strict"
}
});
Session Validation
import { NextRequest , NextResponse } from "next/server" ;
export async function GET ( request : NextRequest ) {
try {
const session = await authServer . getSession (
request ,
NextResponse . next ()
);
return NextResponse . json ({
userId: session . userId ,
authenticated: true
});
} catch ( error ) {
return NextResponse . json (
{ error: "Unauthorized" },
{ status: 401 }
);
}
}
JWT Verification
Verify and decode JWT tokens:
try {
const decoded = await authServer . verifyCrossmintJwt ( token );
console . log ( "User ID:" , decoded . sub );
console . log ( "Expires:" , decoded . exp );
} catch ( error ) {
console . error ( "Invalid JWT" );
}
Custom Refresh Route
Implement a custom refresh endpoint:
export async function POST ( request : NextRequest ) {
const response = NextResponse . next ();
try {
const refreshedResponse = await authServer . handleCustomRefresh (
request ,
response
);
return refreshedResponse ;
} catch ( error ) {
return NextResponse . json (
{ error: "Failed to refresh session" },
{ status: 401 }
);
}
}
Logout
export async function POST ( request : NextRequest ) {
const response = NextResponse . next ();
const logoutResponse = await authServer . logout ( request , response );
return logoutResponse ;
}
Authentication Flow
Complete Authentication Flow Diagram
Best Practices
Use Server SDK for Protected Routes Validate sessions on your backend using CrossmintAuthServer to prevent token tampering.
Handle Token Refresh Automatically The client SDK automatically refreshes tokens before expiration. Listen to onTokenRefresh callbacks for updates.
Secure Your Cookies Use httpOnly, secure, and sameSite cookie options in production to prevent XSS attacks.
Implement Custom Logout Route Create a server-side logout endpoint to properly clear cookies and invalidate refresh tokens.
Error Handling
import { CrossmintAuthenticationError } from "@crossmint/common-sdk-auth" ;
try {
await auth . confirmEmailOtp ( email , emailId , otp );
} catch ( error ) {
if ( error instanceof CrossmintAuthenticationError ) {
console . error ( "Authentication failed:" , error . message );
}
}
Next Steps
Create Wallets Learn how to create and manage embedded wallets for authenticated users
Configure Signers Understand different signer types for wallet transactions