Hono 集成

在开始之前,确保您已配置 Better Auth 实例。如果尚未完成,请查看 installation

挂载处理程序

我们需要将处理程序挂载到 Hono 端点。

import { Hono } from "hono";
import { auth } from "./auth";
import { serve } from "@hono/node-server";

const app = new Hono();

app.on(["POST", "GET"], "/api/auth/*", (c) => {
	return auth.handler(c.req.raw);
});

serve(app);

CORS

要配置 CORS,您需要使用 hono/cors 中的 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/*", // 或替换为 "*" 以为所有路由启用 CORS
	cors({
		origin: "http://localhost:3001", // 替换为您的源
		allowHeaders: ["Content-Type", "Authorization"],
		allowMethods: ["POST", "GET", "OPTIONS"],
		exposeHeaders: ["Content-Length"],
		maxAge: 600,
		credentials: true,
	}),
);

app.on(["POST", "GET"], "/api/auth/*", (c) => {
	return auth.handler(c.req.raw);
});

serve(app);

重要: CORS 中间件必须在您的路由之前注册。这确保了跨源请求在到达您的认证端点之前得到正确处理。

中间件

您可以添加一个中间件来在上下文中保存 sessionuser,并为每个路由添加验证。

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);

这将允许您在所有路由中访问 usersession 对象。

app.get("/session", (c) => {
	const session = c.get("session")
	const user = c.get("user")
	
	if(!user) return c.body(null, 401);

  	return c.json({
	  session,
	  user
	});
});

默认情况下,所有 Better Auth Cookie 都设置为 SameSite=Lax。如果您需要跨不同域使用 Cookie,则需要设置 SameSite=NoneSecure=true。但是,我们推荐尽可能使用子域,因为这允许您保持 SameSite=Lax。要启用跨子域 Cookie,只需在您的认证配置中开启 crossSubDomainCookies

auth.ts
export const auth = createAuth({
  advanced: {
    crossSubDomainCookies: {
      enabled: true
    }
  }
})

如果您仍然需要设置 SameSite=NoneSecure=true,您可以通过 createAuth 配置中的 cookieOptions 全局调整这些属性。

auth.ts
export const auth = createAuth({
  advanced: {
    defaultCookieAttributes: {
      sameSite: "none",
      secure: true,
      partitioned: true // 新浏览器标准将要求此项用于外来 Cookie
    }
  }
})

您也可以通过在认证配置中的 cookies 内单独设置来自定义 Cookie 属性。

auth.ts
export const auth = createAuth({
  advanced: {
    cookies: {
      sessionToken: {
        attributes: {
          sameSite: "none",
          secure: true,
          partitioned: true // 新浏览器标准将要求此项用于外来 Cookie
        }
      }
    }
  }
})

客户端配置

在使用 Hono 客户端 (@hono/client) 向您的 Better Auth 保护端点发出请求时,您需要配置它以在跨源请求中发送凭据(Cookie)。

api.ts
import { hc } from "hono/client";
import type { AppType } from "./server"; // 您的 Hono 应用类型

const client = hc<AppType>("http://localhost:8787/", {
  init: {
    credentials: "include", // 跨源发送 Cookie 所需
  },
});

// 现在您的客户端请求将包含凭据
const response = await client.someProtectedEndpoint.$get();

此配置在以下情况下是必要的:

  • 开发期间您的客户端和服务器位于不同域/端口
  • 生产环境中进行跨源请求
  • 您需要与请求一起发送认证 Cookie

credentials: "include" 选项告诉 fetch 客户端即使对于跨源请求也要发送 Cookie。这与服务器上具有 credentials: true 的 CORS 配置配合使用。

注意: 确保服务器上的 CORS 配置与客户端的域匹配,并且在服务器的 CORS 配置和客户端的 fetch 配置中都设置了 credentials: true

On this page