Cookies
Session cookie configuration and behavior.
Better Auth uses HTTP cookies to persist session tokens in the browser. This page explains how cookies are configured and the security implications of each setting.
Default Cookie Settings
By default, Better Auth sets session cookies with the following attributes:
| Attribute | Default | Description |
|---|---|---|
| Name | better-auth.session-token | Cookie name |
| Path | / | Available on all paths |
| Secure | true | HTTPS only by default (disable for local HTTP development) |
| HttpOnly | true | Not accessible via JavaScript |
| SameSite | Lax | CSRF protection with top-level navigation support |
Configuration
Configure cookie behavior through AuthConfig:
use better_auth::{AuthConfig, SameSite};
use chrono::Duration;
let mut config = AuthConfig::new("your-secret-key-at-least-32-chars");
config.session.cookie_name = "my-app.session".to_string();
config.session.cookie_secure = true;
config.session.cookie_http_only = true;
config.session.cookie_same_site = SameSite::Lax;
config.session.expires_in = Duration::hours(24 * 7); // 7 daysCookie Attributes
Secure
When true, the cookie is only sent over HTTPS connections. This prevents session tokens from being transmitted in plaintext.
config.session.cookie_secure = true;Always set Secure: true in production. Only disable it for local development over HTTP.
HttpOnly
When true, the cookie cannot be accessed by JavaScript (document.cookie). This prevents XSS attacks from stealing session tokens.
config.session.cookie_http_only = true;Always keep this enabled unless you have a specific reason to access the session token from JavaScript.
SameSite
Controls when the cookie is sent with cross-site requests:
| Value | Behavior |
|---|---|
Strict | Cookie only sent for same-site requests. Most secure but may break OAuth redirects. |
Lax | Cookie sent for same-site requests and top-level navigations (GET only). Recommended default. |
None | Cookie sent for all requests. Requires Secure: true. Use for cross-origin API access. |
use better_auth::SameSite;
// Recommended for most applications
config.session.cookie_same_site = SameSite::Lax;
// For cross-origin API access (requires Secure: true)
config.session.cookie_same_site = SameSite::None;Expiration
The cookie expiration matches the session expiration time. When a session is created, the Expires attribute is set accordingly.
use chrono::Duration;
// Session and cookie expire after 7 days
config.session.expires_in = Duration::hours(24 * 7);Cookie Format
The session cookie is set via the Set-Cookie HTTP header:
Set-Cookie: better-auth.session-token=session_abc123...; Path=/; Expires=Thu, 08 Jan 2025 00:00:00 GMT; Secure; HttpOnly; SameSite=LaxCross-Origin Usage
If your frontend and backend are on different origins, you need to:
- Set
SameSite::NoneandSecure: trueon the cookie - Configure CORS to allow credentials:
use better_auth::CorsConfig;
let auth = BetterAuth::new(config)
.cors(
CorsConfig::new()
.allowed_origin("https://frontend.example.com")
.allow_credentials(true)
)
.build()
.await?;- Include credentials in frontend requests:
fetch('https://api.example.com/auth/get-session', {
credentials: 'include' // Send cookies cross-origin
});Alternative: Bearer Token
If you prefer not to use cookies (e.g., for mobile apps or API clients), you can use the Authorization header instead:
Authorization: Bearer session_abc123...Both methods are supported simultaneously. The session token is extracted from the cookie or the Authorization header, whichever is present.
See Also
- Sessions — Session lifecycle and endpoints
- Security — Security best practices
- Middleware — CORS configuration