Hono 集成

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

挂载处理程序

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

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

跨域资源共享(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,
	}),
);

中间件

你可以添加中间件将 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", async (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 的 cookies 都设置为 SameSite=Lax。如果你需要在不同域之间使用 cookies,你需要设置 SameSite=NoneSecure=true。但是,我们建议尽可能使用子域,因为这允许你保持 SameSite=Lax。要启用跨子域 cookies,只需在你的 auth 配置中打开 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 // 新的浏览器标准将为外部 cookies 强制要求这一点
    }
  }
})

你也可以通过在 auth 配置的 cookies 中设置来单独自定义 cookie 属性。

auth.ts
export const auth = createAuth({
  advanced: {
    cookies: {
      sessionToken: {
        sameSite: "none",
        secure: true,
        partitioned: true // 新的浏览器标准将为外部 cookies 强制要求这一点
      }
    }
  }
})

客户端配置

当使用 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/", {
  fetch: ((input, init) => {
    return fetch(input, { 
      ...init, 
      credentials: "include" // 跨域发送 cookies 所需
    });
  }) satisfies typeof fetch,
});
 
// 现在你的客户端请求将包含凭证
const response = await client.someProtectedEndpoint.$get();

在以下情况下需要此配置:

  • 在开发过程中,你的客户端和服务器位于不同的域/端口上
  • 你在生产环境中进行跨域请求
  • 你需要随请求发送认证 cookies

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

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

On this page