Before you start, make sure you have a Better Auth instance configured. If you haven't done that yet, check out the installation .
We need to mount the handler to Hono endpoint.
import { Hono } from "hono" ;
import { auth } from "./auth" ;
import { serve } from "@hono/node-server" ;
import { cors } from "hono/cors" ;
const app = new Hono ();
app. on ([ "POST" , "GET" ], "/api/auth/**" , ( c ) => {
return auth. handler (c.req.raw);
});
serve (app);
To configure cors, you need to use the cors
plugin from hono/cors
.
import { Hono } from "hono" ;
import { auth } from "./auth" ;
import { serve } from "@hono/node-server" ;
import { cors } from "hono/cors" ;
const app = new Hono ();
app. use (
"/api/auth/**" , // or replace with "*" to enable cors for all routes
cors ({
origin: "http://localhost:3001" , // replace with your origin
allowHeaders: [ "Content-Type" , "Authorization" ],
allowMethods: [ "POST" , "GET" , "OPTIONS" ],
exposeHeaders: [ "Content-Length" ],
maxAge: 600 ,
credentials: true ,
}),
);
You can add a middleware to save the session
and user
in a context
and also add validations for every route.
import { Hono } from "hono" ;
import { auth } from "./auth" ;
import { serve } from "@hono/node-server" ;
import { cors } from "hono/cors" ;
const app = new Hono <{
Variables : {
user : typeof auth.$Infer.Session.user | null ;
session : typeof auth.$Infer.Session.session | null
}
}>();
app. use ( "*" , async ( c , next ) => {
const session = await auth.api. getSession ({ headers: c.req.raw.headers });
if ( ! session) {
c. set ( "user" , null );
c. set ( "session" , null );
return next ();
}
c. set ( "user" , session.user);
c. set ( "session" , session.session);
return next ();
});
app. on ([ "POST" , "GET" ], "/api/auth/**" , ( c ) => {
return auth. handler (c.req.raw);
});
serve (app);
This will allow you to access the user
and session
object in all of your routes.
app. get ( "/session" , async ( c ) => {
const session = c. get ( "session" )
const user = c. get ( "user" )
if ( ! user) return c. body ( null , 401 );
return c. json ({
session,
user
});
});
By default, all Better Auth cookies are set with SameSite=Lax
. If you need to use cookies across different domains, you’ll need to set SameSite=None
and Secure=true
. However, we recommend using subdomains whenever possible, as this allows you to keep SameSite=Lax
. To enable cross-subdomain cookies, simply turn on crossSubDomainCookies
in your auth config.
export const auth = createAuth ({
advanced: {
crossSubDomainCookies: {
enabled: true
}
}
})
If you still need to set SameSite=None
and Secure=true
, you can adjust these attributes globally through cookieOptions
in the createAuth
configuration.
export const auth = createAuth ({
advanced: {
defaultCookieAttributes: {
sameSite: "none" ,
secure: true
}
}
})
You can also customize cookie attributes individually by setting them within cookies
in your auth config.
export const auth = createAuth ({
advanced: {
cookies: {
sessionToken: {
sameSite: "none" ,
secure: true
}
}
}
})