Cookies(Cookie)
了解 Better Auth 中 Cookies 的使用。
Cookies 用于存储诸如会话令牌、会话数据、OAuth 状态等信息。所有 Cookies 都使用认证选项中提供的 secret 密钥或环境变量 BETTER_AUTH_SECRET 进行签名。如果您使用 版本化密钥 来进行密钥轮换,加密的 Cookie 数据(例如 JWE 会话缓存)将自动使用当前密钥,并且仍然可以用之前的密钥解密。
Cookie 前缀
默认情况下,Better Auth 的 Cookies 格式为 ${prefix}.${cookie_name}。默认前缀是 "better-auth"。您可以通过在认证选项的 advanced 对象中设置 cookiePrefix 来更改前缀。
import { betterAuth } from "better-auth"
export const auth = betterAuth({
advanced: {
cookiePrefix: "my-app"
}
})自定义 Cookies
在服务器运行于生产模式时,所有 Cookies 都是 httpOnly 和 secure 的。
如果您想设置自定义的 Cookie 名称和属性,可以通过在认证选项的 advanced 对象中设置 cookieOptions 来实现。
默认情况下,Better Auth 使用以下 Cookies:
session_token用于存储会话令牌session_data用于在启用 Cookie 缓存时存储会话数据dont_remember用于存储当rememberMe被禁用时的标志
插件也可能使用 Cookies 来存储数据。例如,双因素认证插件使用 two_factor Cookie 来存储双因素认证状态。
import { betterAuth } from "better-auth"
export const auth = betterAuth({
advanced: {
cookies: {
session_token: {
name: "custom_session_token",
attributes: {
// 设置自定义的 Cookie 属性
}
},
}
}
})跨子域 Cookies
有时您可能需要在子域间共享 Cookies。
例如,如果您在 auth.example.com 进行身份验证,您可能也想在 app.example.com 访问相同的会话。
domain 属性控制哪些域可以访问该 Cookie。将其设置为根域(例如 example.com)将使 Cookie 在所有子域间可访问。为了安全,请遵循以下指南:
- 仅当必要时启用跨子域 Cookies
- 将域设置为所需的最具体范围(例如,使用
app.example.com而非.example.com) - 警惕可能访问这些 Cookies 的不受信任的子域
- 考虑为不受信任的服务使用不同的域(例如
status.company.com与app.company.com)
import { betterAuth } from "better-auth"
export const auth = betterAuth({
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: "app.example.com", // 您的域名
},
},
trustedOrigins: [
'https://example.com',
'https://app1.example.com',
'https://app2.example.com',
],
})安全 Cookies
默认情况下,只有在服务器运行于生产环境时,Cookies 才是安全的。您可以通过在认证选项的 advanced 对象中设置 useSecureCookies 为 true,强制 Cookies 始终使用安全模式。
import { betterAuth } from "better-auth"
export const auth = betterAuth({
advanced: {
useSecureCookies: true
}
})Safari、ITP 与跨域设置
Safari 内建了一个隐私功能,称为智能追踪防护(Intelligent Tracking Prevention,简称 ITP),会阻止第三方 Cookies。
如果您的 Better Auth API 托管在与前端不同的域名下,Safari 可能完全阻止身份验证 Cookies。
以下示例在 Safari 中会失败:
前端: https://app.domainB.com
API: https://domainA.com如果您的前端发起类似以下请求:
fetch("https://domainA.com/api/auth/get-session", {
credentials: "include"
})Safari 会将 domainA.com 视为第三方,阻止其 Cookies。这可能导致会话无法持久化,
Set-Cookie 头被忽略,用户在登录后依然显示未登录状态,或是在 Chrome 中工作正常但 Safari 中失败。
为解决此问题,有两种方案:
- 使用反向代理将请求代理到 API。
- 使用共享的父域名。
使用反向代理
您可以通过与前端相同域名的反向代理来访问 API,而不是直接调用它。
例如,不调用:
https://domainA.com/api/auth/*而调用:
https://app.domainA.com/api/auth/*然后配置您的托管服务,将请求代理到实际的 API 服务器。
这样请求在 Safari 中被视作为同源请求,从而允许 Cookies 正常工作。
Netlify 示例
[[redirects]]
from = "/api/*"
to = "https://domainA.com/api/:splat"
status = 200
force = trueVercel 示例
{
"rewrites": [
{
"source": "/api/:path*",
"destination": "https://domainA.com/api/:path*"
}
]
}使用共享父域名
您也可以使用共享的父域名来允许 Cookies 跨子域共享:
https://app.example.com
https://api.example.com然后启用跨子域 Cookies 并设置域为:
import { betterAuth } from "better-auth"
export const auth = betterAuth({
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: "example.com",
},
},
})更多关于跨子域 Cookies 的内容,请参见 上述文档。
这样可以避免 Safari 将 API 识别为第三方。