Hono 集成

将 Better Auth 集成到 Hono。

Hono 和 Better Auth 都使用 Web Standard Request 和 Response API,因此你可以直接在 Hono 应用中挂载 Better Auth,而无需适配器。

开始之前,请确保你已配置 Better Auth 实例。如果还没有,请按照安装指南操作。

设置

创建 Hono 应用

如果你要开始一个新项目,请创建一个 Hono 应用,并为你的运行时或平台选择模板:

npx create-hono@latest

如果你已经有 Hono 应用,则可以跳过此步骤。请参阅create-hono 文档了解可用的模板和选项,或参阅 Hono 的入门指南了解特定运行时的设置和部署。

挂载 Auth 处理程序

将高亮显示的路由添加到现有的 Hono 应用中:

src/index.ts
import { Hono } from "hono";
import { auth } from "./auth";

const app = new Hono();

app.all("/api/auth/*", (c) => auth.handler(c.req.raw)); 

export default app;

这样就完成了将 Better Auth 连接到 Hono 所需的全部操作!

如果你使用的是其他运行时,请保留现有入口点,并添加相同的 app.all() 路由。

app.all() 使用来自 c.req.raw 的原始 Web Standard Request 将每个 HTTP 方法转发给 Better Auth。Better Auth 会验证方法,并返回一个由 Hono 直接发送的 Response。请在任何可能先处理请求的全捕获路由之前注册 Auth 路由。

最终的 Hono 路由必须与 Better Auth 的 basePath 匹配,该值默认为 /api/auth。如果你的应用已经使用了 new Hono().basePath("/api"),请将 Better Auth 挂载到 /auth/*:

const app = new Hono().basePath("/api");

app.all("/auth/*", (c) => auth.handler(c.req.raw));

其他配置

Cloudflare Workers

Better Auth 使用 AsyncLocalStorage。请将 nodejs_compat 兼容性标志添加到你的 Wrangler 配置中:

wrangler.jsonc
{
  // Use "nodejs_als" instead if you only need AsyncLocalStorage.
  "compatibility_flags": ["nodejs_compat"],
}

CORS

要允许跨源身份验证请求,请在 Better Auth 路由之前注册 Hono 的CORS 中间件:

src/index.ts
import { Hono } from "hono";
import { cors } from "hono/cors"; 
import { auth } from "./auth";

const app = new Hono();

app.use( 
	"/api/auth/*", 
	cors({ 
		origin: "http://localhost:3001", 
		credentials: true, 
	}), 
); 

app.all("/api/auth/*", (c) => auth.handler(c.req.raw));

export default app;

将相同的源添加到 Better Auth 的 trustedOrigins 配置中:

auth.ts
import { betterAuth } from "better-auth";

export const auth = betterAuth({
	trustedOrigins: ["http://localhost:3001"], 
});

启用 credentials 后,请配置明确的 CORS 源,而不是使用 *,并将相同的源添加到 Better Auth 的 trustedOrigins 中。请参阅 Cookies 了解跨域和跨子域 Cookie 的行为。

中间件

你还可以使用自定义中间件,通过 Hono 的上下文提供当前会话:

src/session-middleware.ts
import { createMiddleware } from "hono/factory";
import { auth } from "./auth";

type Env = {
	Variables: {
		session: typeof auth.$Infer.Session | null;
	};
};

export const sessionMiddleware = createMiddleware<Env>(async (c, next) => {
	const session = await auth.api.getSession({
		headers: c.req.raw.headers,
	});

	c.set("session", session);

	await next();
});

将中间件添加到任何需要访问当前会话的路由:

src/index.ts
import { Hono } from "hono";
import { HTTPException } from "hono/http-exception";
import { sessionMiddleware } from "./session-middleware";

const app = new Hono();

app.get("/hello", sessionMiddleware, (c) => {
	const session = c.get("session");

	if (!session) {
		throw new HTTPException(401);
	}

	return c.json({ message: `Hello, ${session.user.name}.` });
});

export default app;

此示例将中间件应用于单个路由。有关其他模式,请参阅 Hono 的中间件指南。

Hono RPC

Better Auth 客户端默认使用 credentials: "include"。如果你使用 Hono RPC 从其他源调用需要身份验证的 Hono 路由,请将 RPC 客户端配置为同样包含凭据:

此配置仅适用于跨源请求。有关更多信息,请参阅 Hono 的RPC Cookie 指南。