Hono 集成

在开始之前,请确保您已经配置了 Better Auth 实例。如果尚未完成,请查看安装指南

挂载处理器

我们需要将处理器挂载到 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 保存在 context 中,并为每个路由添加验证。

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 保护的端点发送请求时,需要配置它以在跨域请求中发送凭据(cookies)。

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

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

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

以下情况需要此配置:

  • 开发期间客户端和服务器位于不同域名/端口
  • 生产环境中进行跨域请求
  • 需要在请求中发送身份验证 cookies

credentials: "include" 选项告诉 fetch 客户端即使在跨域请求时也要发送 cookies。这与服务器上设置了 credentials: true 的 CORS 配置协同工作。

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

On this page