better-auth-tauri-setup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBetter Auth Tauri Plugin - Setup Guide
Better Auth Tauri 插件 - 安装指南
Package: (v0.1.6+)
Purpose: Enables cookie-based authentication in Tauri v2 desktop apps using deep links for OAuth callback flows.
@daveyplate/better-auth-tauri包: (v0.1.6+)
用途:通过 OAuth 回调流程的深度链接,在 Tauri v2 桌面应用中启用基于 Cookie 的认证。
@daveyplate/better-auth-tauriArchitecture Overview
架构概述
The plugin works in two halves: a server plugin (Better Auth middleware) and a client setup (Tauri deep link listener). Social OAuth opens in the user's default browser, completes there, then deep-links back into the Tauri app to finalize the session.
该插件分为两部分工作:服务端插件(Better Auth 中间件)和客户端配置(Tauri 深度链接监听器)。社交 OAuth 在用户默认浏览器中打开并完成认证,随后通过深度链接跳转回 Tauri 应用以完成会话建立。
Complete Social Auth Flow
完整社交认证流程
1. User clicks "Sign in with Google" in Tauri app
2. signInSocial() sends request to /api/auth/sign-in/social with Platform header
3. Server middleware appends scheme callback to OAuth redirectURI:
→ /api/auth/callback/google?callbackURL=my-app://
4. Server returns Google OAuth URL; client opens it in default browser
5. User authenticates in browser; Google redirects to callback URL
6. Server middleware intercepts callbackURL with scheme prefix
7. Server redirects to /api/auth/callback/success?redirectTo=my-app://api/auth/callback/google?...
8. Success page HTML triggers: window.location.href = 'my-app://...'
9. OS deep link activates Tauri app
10. Client handleAuthDeepLink() calls authClient.$fetch() to process callback
11. Server validates OAuth code, creates session, sets cookie
12. onSuccess callback fires - auth complete1. 用户在 Tauri 应用中点击“使用 Google 登录”
2. signInSocial() 向 /api/auth/sign-in/social 发送请求,附带 Platform 请求头
3. 服务端中间件在 OAuth 的 redirectURI 后追加 scheme 回调地址:
→ /api/auth/callback/google?callbackURL=my-app://
4. 服务端返回 Google OAuth 地址;客户端在默认浏览器中打开该地址
5. 用户在浏览器中完成认证;Google 重定向到回调地址
6. 服务端中间件拦截带有 scheme 前缀的 callbackURL 请求
7. 服务端重定向到 /api/auth/callback/success?redirectTo=my-app://api/auth/callback/google?...
8. 成功页面的 HTML 触发:window.location.href = 'my-app://...'
9. 系统深度链接激活 Tauri 应用
10. 客户端调用 handleAuthDeepLink(),通过 authClient.$fetch() 处理回调
11. 服务端验证 OAuth 授权码,创建会话并设置 Cookie
12. onSuccess 回调触发——认证完成Prerequisites
前置条件
Required Tauri Plugins (peer dependencies)
必需的 Tauri 插件(对等依赖)
bash
bun add @tauri-apps/api @tauri-apps/plugin-deep-link @tauri-apps/plugin-http @tauri-apps/plugin-os @tauri-apps/plugin-opener better-auth| Plugin | Min Version | Purpose |
|---|---|---|
| >=2.5.0 | Core Tauri API, |
| >=2.2.1 | URL scheme handling ( |
| >=2.4.3 | HTTP with cookie support (macOS fix) |
| >=2.2.1 | Platform detection |
| >=2.2.6 | Open OAuth URLs in default browser |
| >=1.2.7 | Authentication framework |
bash
bun add @tauri-apps/api @tauri-apps/plugin-deep-link @tauri-apps/plugin-http @tauri-apps/plugin-os @tauri-apps/plugin-opener better-auth| 插件 | 最低版本 | 用途 |
|---|---|---|
| >=2.5.0 | Tauri 核心 API,用于 |
| >=2.2.1 | URL scheme 处理( |
| >=2.4.3 | 支持 Cookie 的 HTTP 请求(修复 macOS 兼容问题) |
| >=2.2.1 | 平台检测 |
| >=2.2.6 | 在默认浏览器中打开 OAuth 地址 |
| >=1.2.7 | 认证框架 |
Tauri Deep Link Config
Tauri 深度链接配置
In :
tauri.conf.jsonjson
{
"plugins": {
"deep-link": {
"desktop": {
"schemes": ["my-app"]
}
}
}
}在 中:
tauri.conf.jsonjson
{
"plugins": {
"deep-link": {
"desktop": {
"schemes": ["my-app"]
}
}
}
}Server Setup
服务端配置
Plugin Registration (auth.ts)
插件注册(auth.ts)
typescript
import { betterAuth } from "better-auth"
import { tauri } from "@daveyplate/better-auth-tauri/plugin"
export const auth = betterAuth({
// ... your existing config
plugins: [
tauri({
scheme: "my-app", // Must match tauri.conf.json and client
callbackURL: "/", // Where to redirect after auth (default: "/")
successText: "Authentication successful! You can close this window.",
successURL: undefined, // Custom success page URL (gets ?redirectTo param)
debugLogs: false, // Enable server-side debug logging
}),
],
})typescript
import { betterAuth } from "better-auth"
import { tauri } from "@daveyplate/better-auth-tauri/plugin"
export const auth = betterAuth({
// ... 您现有的配置
plugins: [
tauri({
scheme: "my-app", // 必须与 tauri.conf.json 和客户端配置一致
callbackURL: "/", // 认证完成后的重定向地址(默认:"/")
successText: "认证成功!您可以关闭此窗口。",
successURL: undefined, // 自定义成功页面地址(会接收 ?redirectTo 参数)
debugLogs: false, // 启用服务端调试日志
}),
],
})Plugin Options
插件选项
| Option | Type | Default | Description |
|---|---|---|---|
| | required | Deep link scheme (without |
| | | Post-auth redirect path |
| | Generic message | Text shown on browser success page |
| | | Custom success page URL (receives |
| | | Log middleware activity to console |
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| | 必填 | 深度链接 scheme(不含 |
| | | 认证后的重定向路径 |
| | 通用提示语 | 浏览器成功页面显示的文本 |
| | | 自定义成功页面地址(会接收 |
| | | 在控制台输出中间件活动日志 |
What the Server Plugin Does
服务端插件功能
The plugin registers:
-
Before-hook middleware on all routes (exceptand
/reset-password):/callback/success- : On
appendCallbackURL()requests with a/sign-in/socialheader (non-mobile), modifies each social provider'sPlatformto includeredirectURI?callbackURL=scheme:// - : On any request where
checkCallbackURL()query param starts withcallbackURL, strips the scheme and redirects to the success page with the deep link URL encoded inscheme://?redirectTo=
-
Endpoint: Returns HTML success page with embedded
/callback/successto trigger the OS deep link<script>window.location.href = '{deepLinkURL}'</script>
该插件会注册:
-
所有路由的前置钩子中间件(除了和
/reset-password):/callback/success- :当
appendCallbackURL()请求带有/sign-in/social请求头(非移动端)时,修改每个社交提供商的Platform,追加redirectURI?callbackURL=scheme:// - :当任何请求的
checkCallbackURL()查询参数以callbackURL开头时,移除 scheme 并将请求重定向到成功页面,同时将深度链接地址编码到scheme://参数中?redirectTo=
-
端点:返回包含
/callback/success的 HTML 成功页面,触发系统深度链接<script>window.location.href = '{deepLinkURL}'</script>
Client Setup
客户端配置
Auth Client with macOS Cookie Fix
适配 macOS Cookie 问题的认证客户端
Critical: macOS production builds require for cookies to work.
@tauri-apps/plugin-httptypescript
// lib/auth-client.ts
import { isTauri } from "@tauri-apps/api/core"
import { fetch as tauriFetch } from "@tauri-apps/plugin-http"
import { platform } from "@tauri-apps/plugin-os"
import { createAuthClient } from "better-auth/react" // or "better-auth/client"
export const authClient = createAuthClient({
fetchOptions: {
customFetchImpl: (...params) =>
isTauri() && platform() === "macos" && window.location.protocol === "tauri:"
? tauriFetch(...params)
: fetch(...params)
}
})关键注意:macOS 生产构建需要 才能正常使用 Cookie。
@tauri-apps/plugin-httptypescript
// lib/auth-client.ts
import { isTauri } from "@tauri-apps/api/core"
import { fetch as tauriFetch } from "@tauri-apps/plugin-http"
import { platform } from "@tauri-apps/plugin-os"
import { createAuthClient } from "better-auth/react" // 或 "better-auth/client"
export const authClient = createAuthClient({
fetchOptions: {
customFetchImpl: (...params) =>
isTauri() && platform() === "macos" && window.location.protocol === "tauri:"
? tauriFetch(...params)
: fetch(...params)
}
})Standard JS/TS Setup
标准 JS/TS 配置
typescript
import { setupBetterAuthTauri } from "@daveyplate/better-auth-tauri"
import { authClient } from "./lib/auth-client"
const cleanup = setupBetterAuthTauri({
authClient,
scheme: "my-app", // Must match server config
debugLogs: false,
mainWindowLabel: "main", // Tauri window label (default: "main")
onRequest: (href) => {
console.log("Processing auth callback:", href)
},
onSuccess: (callbackURL) => {
window.location.href = callbackURL || "/"
},
onError: (error) => {
// error: { status: number, statusText: string, code?: string, message?: string }
console.error("Auth failed:", error.status, error.statusText)
},
})
// Call cleanup() when done (e.g., component unmount)typescript
import { setupBetterAuthTauri } from "@daveyplate/better-auth-tauri"
import { authClient } from "./lib/auth-client"
const cleanup = setupBetterAuthTauri({
authClient,
scheme: "my-app", // 必须与服务端配置一致
debugLogs: false,
mainWindowLabel: "main", // Tauri 窗口标签(默认:"main")
onRequest: (href) => {
console.log("处理认证回调:", href)
},
onSuccess: (callbackURL) => {
window.location.href = callbackURL || "/"
},
onError: (error) => {
// error: { status: number, statusText: string, code?: string, message?: string }
console.error("认证失败:", error.status, error.statusText)
},
})
// 完成后调用 cleanup()(例如组件卸载时)React Setup
React 配置
tsx
import { useBetterAuthTauri } from "@daveyplate/better-auth-tauri/react"
import { authClient } from "./lib/auth-client"
function App() {
useBetterAuthTauri({
authClient,
scheme: "my-app",
onSuccess: (callbackURL) => {
navigate(callbackURL || "/")
},
onError: (error) => {
toast.error(`Auth failed: ${error.statusText}`)
},
})
return <YourApp />
}tsx
import { useBetterAuthTauri } from "@daveyplate/better-auth-tauri/react"
import { authClient } from "./lib/auth-client"
function App() {
useBetterAuthTauri({
authClient,
scheme: "my-app",
onSuccess: (callbackURL) => {
navigate(callbackURL || "/")
},
onError: (error) => {
toast.error(`认证失败: ${error.statusText}`)
},
})
return <YourApp />
}Svelte Setup
Svelte 配置
svelte
<script>
import { onMount, onDestroy } from "svelte"
import { setupBetterAuthTauri } from "@daveyplate/better-auth-tauri"
import { authClient } from "./lib/auth-client"
import { goto } from "$app/navigation"
let cleanup
onMount(() => {
cleanup = setupBetterAuthTauri({
authClient,
scheme: "my-app",
onSuccess: (callbackURL) => goto(callbackURL || "/"),
onError: (error) => console.error("Auth error:", error),
})
})
onDestroy(() => cleanup?.())
</script>svelte
<script>
import { onMount, onDestroy } from "svelte"
import { setupBetterAuthTauri } from "@daveyplate/better-auth-tauri"
import { authClient } from "./lib/auth-client"
import { goto } from "$app/navigation"
let cleanup
onMount(() => {
cleanup = setupBetterAuthTauri({
authClient,
scheme: "my-app",
onSuccess: (callbackURL) => goto(callbackURL || "/"),
onError: (error) => console.error("认证错误:", error),
})
})
onDestroy(() => cleanup?.())
</script>Social Sign-In
社交登录
Social auth opens in the user's default browser (reuses logged-in sessions). Use the provided helper:
tsx
import { signInSocial } from "@daveyplate/better-auth-tauri"
import { authClient } from "./lib/auth-client"
<button onClick={async () => {
const { data, error } = await signInSocial({
authClient,
provider: "google", // Any configured social provider
})
if (error) console.error("Social sign-in error:", error)
}}>
Sign in with Google
</button>社交认证会在用户默认浏览器中打开(复用已登录会话)。使用提供的工具函数:
tsx
import { signInSocial } from "@daveyplate/better-auth-tauri"
import { authClient } from "./lib/auth-client"
<button onClick={async () => {
const { data, error } = await signInSocial({
authClient,
provider: "google", // 任何已配置的社交提供商
})
if (error) console.error("社交登录错误:", error)
}}>
使用 Google 登录
</button>What signInSocial Does
signInSocial 功能说明
- Checks if Opener plugin is available (+ correct protocol)
isTauri() - Sends sign-in request with header (triggers server-side callback URL appending)
Platform - Sets to prevent in-app redirect
disableRedirect: true - Opens returned OAuth URL in default browser via
openUrl() - Supports for exception-based error handling
fetchOptions.throw: true
- 检查 Opener 插件是否可用(+ 正确协议)
isTauri() - 发送带有 请求头的登录请求(触发服务端回调地址追加逻辑)
Platform - 设置 以避免应用内重定向
disableRedirect: true - 通过 在默认浏览器中打开返回的 OAuth 地址
openUrl() - 支持 实现基于异常的错误处理
fetchOptions.throw: true
Non-Social Auth (Magic Link, Email OTP)
非社交认证(魔法链接、邮箱OTP)
Works via the plugin option. The email link contains the deep link scheme directly. No special client-side helper needed - just configure in the server plugin and the link in the email will deep-link back to the app.
callbackURLscheme通过 插件选项实现。邮箱链接直接包含深度链接 scheme。无需特殊客户端工具函数——只需在服务端插件中配置 ,邮箱中的链接即可直接深度链接回应用。
callbackURLschemePackage Exports
包导出
@daveyplate/better-auth-tauri → setupBetterAuthTauri, signInSocial, handleAuthDeepLink
@daveyplate/better-auth-tauri/react → useBetterAuthTauri (React hook)
@daveyplate/better-auth-tauri/plugin → tauri (server plugin factory)@daveyplate/better-auth-tauri → setupBetterAuthTauri, signInSocial, handleAuthDeepLink
@daveyplate/better-auth-tauri/react → useBetterAuthTauri(React 钩子)
@daveyplate/better-auth-tauri/plugin → tauri(服务端插件工厂)Quick Checklist
快速检查清单
- Install all 5 Tauri plugin peer dependencies
- Register deep link scheme in
tauri.conf.json - Add plugin to server
tauri()config with matching schemebetterAuth() - Configure in auth client for macOS cookies
customFetchImpl - Call (or
setupBetterAuthTauri()) in app entry pointuseBetterAuthTauri - Use helper for social providers (not
signInSocial()directly)authClient.signIn.social() - Ensure server has a root route handler () to avoid 404 on post-auth redirect
GET / - Scheme must be identical across: , server plugin, and client setup
tauri.conf.json
- 安装所有5个Tauri插件对等依赖
- 在 中注册深度链接 scheme
tauri.conf.json - 在服务端 配置中添加
betterAuth()插件,并使用匹配的 schemetauri() - 在认证客户端中配置 以适配 macOS Cookie
customFetchImpl - 在应用入口调用 (或
setupBetterAuthTauri())useBetterAuthTauri - 使用 工具函数处理社交提供商(不要直接使用
signInSocial())authClient.signIn.social() - 确保服务端有根路由处理器(),避免认证后重定向出现404
GET / - scheme 必须在以下位置保持一致:、服务端插件、客户端配置
tauri.conf.json
Related Skills
相关技能
- sawy-better-auth-ui-tauri-repro: Reproduction and fix for the module-load-time crash in non-HTTP environments (
@daveyplate/better-auth-ui). Covers pnpm patching, upstream fix proposals, and diagnostic tooling.BetterAuthError: Invalid base URL: tauri://localhost - better-auth-tauri-pitfalls: Debugging guide covering 10 known pitfalls — 404 after OAuth, macOS deep links, cookie persistence, scheme mismatches, and more.
- sawy-better-auth-ui-tauri-repro:针对 在非HTTP环境下加载时崩溃问题的复现与修复(
@daveyplate/better-auth-ui)。涵盖pnpm补丁、上游修复方案和诊断工具。BetterAuthError: Invalid base URL: tauri://localhost - better-auth-tauri-pitfalls:调试指南,涵盖10个已知问题——OAuth后404、macOS深度链接、Cookie持久化、scheme不匹配等。
See also (related skills — Better Auth family)
另请参阅(相关技能 — Better Auth 系列)
If your issue relates to:
- Better Auth integration overview — check if appropriate.
better-auth - best-practices guide — check if appropriate.
better-auth-best-practices - create the auth layer (initial scaffolding) — check if appropriate.
better-auth-create-auth - email/password, password reset, verification policies — check if appropriate.
better-auth-email-password - explain a specific error code + provide fix — check if appropriate.
better-auth-explain-error - organization/team plugin — check if appropriate.
better-auth-organization - OAuth/email/magic-link/social provider config — check if appropriate.
better-auth-providers - rate limit, CSRF, trusted origins, secrets, OAuth security — check if appropriate.
better-auth-security - twoFactor plugin enforcement — check if appropriate.
better-auth-two-factor - Tauri-specific gotchas (cookies, deep links, macOS, 404 callbacks) — check if appropriate.
better-auth-tauri-pitfalls - reproduction guide for the better-auth-ui crash on Tauri v2 — check if appropriate.
sawy-better-auth-ui-tauri-repro
如果您的问题涉及:
- Better Auth 集成概述 — 如有需要,请查看 。
better-auth - 最佳实践指南 — 如有需要,请查看 。
better-auth-best-practices - 创建认证层(初始脚手架) — 如有需要,请查看 。
better-auth-create-auth - 邮箱/密码、密码重置、验证策略 — 如有需要,请查看 。
better-auth-email-password - 解释特定错误码 + 提供修复方案 — 如有需要,请查看 。
better-auth-explain-error - 组织/团队插件 — 如有需要,请查看 。
better-auth-organization - OAuth/邮箱/魔法链接/社交提供商配置 — 如有需要,请查看 。
better-auth-providers - 速率限制、CSRF、可信源、密钥、OAuth安全 — 如有需要,请查看 。
better-auth-security - 双因素插件强制验证 — 如有需要,请查看 。
better-auth-two-factor - Tauri特定问题(Cookie、深度链接、macOS、404回调) — 如有需要,请查看 。
better-auth-tauri-pitfalls - Better-auth-ui在Tauri v2中崩溃问题的复现指南 — 如有需要,请查看 。
sawy-better-auth-ui-tauri-repro