Authentication tokens are accessible to client-side JavaScript by default through non-HttpOnly cookies. For stronger security, you can store tokens in HttpOnly cookies, which are accessible only on the server side. This setup requires custom routes for refreshing tokens and logging out, using utilities from @crossmint/server-sdk
.
When initializing the server SDK, configure secure cookie options:
import { createCrossmint , CrossmintAuth } from "@crossmint/server-sdk" ;
const crossmint = createCrossmint ({ apiKey: process . env . SERVER_CROSSMINT_API_KEY });
const crossmintAuth = CrossmintAuth . from ( crossmint , {
cookieOptions: {
httpOnly: true ,
secure: true , // Only send cookies over HTTPS
domain: ".yourdomain.com" , // Optional: specify cookie domain
},
});
Note: The httpOnly
flag only applies to the refresh token. The session JWT remains accessible to client-side JavaScript since it’s needed for API calls.
2. Custom Routes Implementation
Token Refresh Route
Next.js (App Router) Express.js import { createCrossmint , CrossmintAuth } from "@crossmint/server-sdk" ;
import { NextRequest } from "next/server" ;
const crossmint = createCrossmint ({ apiKey: process . env . SERVER_CROSSMINT_API_KEY ! });
const crossmintAuth = CrossmintAuth . from ( crossmint );
export async function POST ( request : NextRequest ) {
return await crossmintAuth . handleCustomRefresh ( request );
}
import { createCrossmint , CrossmintAuth } from "@crossmint/server-sdk" ;
import { NextRequest } from "next/server" ;
const crossmint = createCrossmint ({ apiKey: process . env . SERVER_CROSSMINT_API_KEY ! });
const crossmintAuth = CrossmintAuth . from ( crossmint );
export async function POST ( request : NextRequest ) {
return await crossmintAuth . handleCustomRefresh ( request );
}
import express from "express" ;
import { createCrossmint , CrossmintAuth } from "@crossmint/server-sdk" ;
const app = express ()
const crossmint = createCrossmint ({ apiKey: process . env . SERVER_CROSSMINT_API_KEY ! });
const crossmintAuth = CrossmintAuth . from ( crossmint );
app . post ( "/api/auth/refresh" , async ( req , res ) => {
await crossmintAuth . handleCustomRefresh ( req , res );
res . end ();
});
Logout Route
Next.js (App Router) Express.js import { createCrossmint , CrossmintAuth } from "@crossmint/server-sdk" ;
import { NextRequest } from "next/server" ;
const crossmint = createCrossmint ({ apiKey: process . env . SERVER_CROSSMINT_API_KEY ! });
const crossmintAuth = CrossmintAuth . from ( crossmint );
export async function POST ( request : NextRequest ) {
return await crossmintAuth . logout ( request );
}
import { createCrossmint , CrossmintAuth } from "@crossmint/server-sdk" ;
import { NextRequest } from "next/server" ;
const crossmint = createCrossmint ({ apiKey: process . env . SERVER_CROSSMINT_API_KEY ! });
const crossmintAuth = CrossmintAuth . from ( crossmint );
export async function POST ( request : NextRequest ) {
return await crossmintAuth . logout ( request );
}
import express from "express" ;
import { createCrossmint , CrossmintAuth } from "@crossmint/server-sdk" ;
const app = express ()
const crossmint = createCrossmint ({ apiKey: process . env . SERVER_CROSSMINT_API_KEY ! });
const crossmintAuth = CrossmintAuth . from ( crossmint );
app . post ( "/api/auth/logout" , async ( req , res ) => {
await crossmintAuth . logout ( req , res );
res . end ();
});
3. Client Configuration
Configure the client SDK to use your custom routes:
import { createCrossmint , CrossmintAuth } from "@crossmint/client-sdk-auth" ;
const crossmint = createCrossmint ({ apiKey: process . env . NEXT_PUBLIC_CLIENT_CROSSMINT_API_KEY ! });
const crossmintAuth = CrossmintAuth . from ( crossmint , {
refreshRoute: "/api/auth/refresh" ,
logoutRoute: "/api/auth/logout"
});
import { createCrossmint , CrossmintAuth } from "@crossmint/client-sdk-auth" ;
const crossmint = createCrossmint ({ apiKey: process . env . NEXT_PUBLIC_CLIENT_CROSSMINT_API_KEY ! });
const crossmintAuth = CrossmintAuth . from ( crossmint , {
refreshRoute: "/api/auth/refresh" ,
logoutRoute: "/api/auth/logout"
});
< CrossmintProvider apiKey = {process.env.NEXT_PUBLIC_CLIENT_CROSSMINT_API_KEY ?? "" } >
< CrossmintAuthProvider
refreshRoute = "/api/auth/refresh"
logoutRoute = "/api/auth/logout"
>
{ children }
</ CrossmintAuthProvider >
</ CrossmintProvider >
Note: Depending on the framework you’re using, you might need to set the whole URL in the refreshRoute
and logoutRoute
options.