# @dreamshive/better-auth-tauri 中文文档

规范地址：https://npmcn.com/package/%40dreamshive/better-auth-tauri/

版本：0\.1\.5
npm 元数据更新时间：2026-11-10T03:59:48.675Z
中文译文更新时间：2026-11-12T23:30:22.740Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40dreamshive/better-auth-tauri
原文对照：https://npmcn.com/package/%40dreamshive/better-auth-tauri/?lang=original
项目主页：https://github.com/DreamsHive/better-auth-tauri#readme
源码仓库：https://github.com/DreamsHive/better-auth-tauri

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：134 kB，38 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：better-auth ^1\.7\.16，@tauri-apps/plugin-shell ^2\.0\.0，@tauri-apps/plugin-deep-link ^2\.0\.0
- 首次发布：2026-04-20T10:30:47.801Z
- 最新版本发布：2026-11-10T03:59:48.311Z
- 近 30 天下载量：3064（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：6（近 12 个月 6 个）

## 中文简介

Tauri桌面应用的更好的Auth插件——通过系统浏览器处理OAuth,使用深链接回调,通过URL进行cookie接通,并安全地存储符钩.

## 安装

```sh
npm install @dreamshive/better-auth-tauri
```

也可以使用：`pnpm add @dreamshive/better-auth-tauri`、`yarn add @dreamshive/better-auth-tauri`、`bun add @dreamshive/better-auth-tauri`

## README

# @dreamshive/better-auth-tauri (英语)

[更好的认证](https://better-auth.com/) 用于 [陶里语Name](https://tauri.app/) 桌面应用程序。 OAuth 发生在用户的 **系统浏览器**,而不是嵌入式的网页视图——会话 cookie通过自定义的 URI 方案深层链接回放,应用程序中每一个向外的请求都是透明认证的.

镜像官员的架构 [`@better-auth/expo`](https://github.com/better-auth/better-auth/tree/main/packages/expo) 软件包,为Tauri浏览器风格的网页视图所改编.

## 为什么要用这个

-   **屏蔽嵌入式网页视图的 OAuth 提供者仍然工作** (谷歌声) `disallowed_useragent`,企业SSO,即将被微软强制执行.
-   **用户重新使用其现有的浏览器会话** (原始内容存档于2017-10-21). – 没有从您应用程序内部重新登录github.com/google.com.
-   **全地址栏 + 挂锁** ——用户在签入前可以验证提供者的域名.
-   **同样更好的 Auth API 表面** 你继续使用 `authClient.signIn.social(...)` 财务报告和审定财务报表 `useSession()` 好像什么都没变一样.

## 如何运作

```
┌──────────────────┐           ┌────────────────┐         ┌──────────────┐
│  Tauri app       │           │ System browser │         │ Auth service │
│  (WKWebView/     │           │ (Safari/Chrome)│         │              │
│   WebView2)      │           │                │         │              │
└────────┬─────────┘           └────────┬───────┘         └──────┬───────┘
         │ signIn.social()              │                        │
         │ ─────────────────────────────┼───────────────────────>│
         │                              │                        │
         │ <── { url, disableRedirect } ──────────────────────────│
         │                              │                        │
         │ shell.open(url)              │                        │
         │ ────────────────────────────>│                        │
         │                              │ /tauri-authz-proxy     │
         │                              │ ──────────────────────>│
         │                              │ Set-Cookie: state=...  │
         │                              │ <──────────────────────│
         │                              │                        │
         │                              │ github.com OAuth...    │
         │                              │ <─redirect to callback─│
         │                              │ /callback/github       │
         │                              │ ──────────────────────>│
         │                              │                        │
         │                              │ <── 302 sokudo://?cookie=<session>
         │                              │     (after-hook appends cookie
         │                              │     to custom-scheme redirect)
         │                              │                        │
         │ <── OS routes sokudo://  ────│                        │
         │                                                       │
         │ store cookie in OS keychain                           │
         │ inject as `x-tauri-cookie` header on future calls     │
         │ ─────────────────────────────────────────────────────>│
         │                                                       │
         │ <── server plugin rewrites x-tauri-cookie → Cookie ───│
         │     Better Auth validates, returns session           │
```

有两件事值得呼吁:

1.  **`x-tauri-cookie` 头部走私.** 获取光谱标记 `Cookie` 作为 [禁用页眉名称](https://fetch.spec.whatwg.org/#forbidden-header-name)。网页视图默默地放弃设置的尝试。 我们把会话偷运出去 `x-tauri-cookie` 编辑 **服务器** 插件重写到 `Cookie` 在更好的Auth检查请求之前.
2.  **`disableRedirect: true` 自动注射.** 更好的 Auth 的 Vue/ React 客户端通常导航 `window.location.href` 到 OAuth URL — 在浏览器中罚款, 在单一窗口的 Tauri app 中灾难性(网页视图与提供者的登录页面相接) 。 客户端插件注入 `disableRedirect: true` 输入 `/sign-in/social` 财务报告和审定财务报表 `/sign-in/oauth2` 请求让客户留在原地.
3.  **Cookie突变被连载.** 反应 cookie, 深链接回调, 和注册共享一个本地突变队列 。 延迟回复可能只撤销它发送的会话,OAuth召回无法在明确退出后恢复会话.

## 安装

```bash
bun add @dreamshive/better-auth-tauri
# or: npm install / pnpm add / yarn add
```

服务器插件需要 `better-auth` 1.7.16 或以后(与 [2026-11-03 安全修复](https://better-auth.com/blog/security-release-2026-11-03)) (中文(简体) ).

Peer Tauri插件( 仅安装在消费客户端的桌面应用中):

```bash
bun add @tauri-apps/plugin-shell @tauri-apps/plugin-deep-link
cd src-tauri
cargo add tauri-plugin-shell tauri-plugin-deep-link
```

如果您想要包含的焦点/在线管理器工作, 您还需要:

```bash
bun add @tauri-apps/api   # onFocusChanged lives here
```

## Tauri 配置

### 1\. 登记你的URI计划

`src-tauri/tauri.conf.json`数字 :

```json
{
  "plugins": {
    "deep-link": {
      "desktop": {
        "schemes": ["yourapp"]
      }
    }
  }
}
```

### 2\. 启动 Rust 插件

`src-tauri/src/lib.rs`数字 :

```rust
pub fn run() {
  tauri::Builder::default()
    .plugin(tauri_plugin_shell::init())
    .plugin(tauri_plugin_deep_link::init())
    // ... your other plugins
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}
```

### 3\. 许可

`src-tauri/capabilities/default.json`数字 :

```json
{
  "permissions": [
    "core:default",
    "shell:allow-open",
    "deep-link:default"
  ]
}
```

### 4\. (高度建议) 添加 `tauri-plugin-single-instance`

没有这个,打开一个 `yourapp://` 在 Tauri app 已经运行时, 从浏览器的深链接可能会生成第二个窗口, 而不是重用第一个窗口 。 安装 :

```bash
cd src-tauri
cargo add tauri-plugin-single-instance --features deep-link
```

登记 **在此之前** 任何其它插件在 `lib.rs`数字 :

```rust
use tauri::{Emitter, Manager};

pub fn run() {
  tauri::Builder::default()
    .plugin(tauri_plugin_single_instance::init(|app, argv, _cwd| {
      if let Some(window) = app.get_webview_window("main") {
        let _ = window.unminimize();
        let _ = window.show();
        let _ = window.set_focus();
      }
      for arg in argv.iter().skip(1) {
        if arg.starts_with("yourapp://") {
          let _ = app.emit("deep-link://new-url", vec![arg.clone()]);
        }
      }
    }))
    .plugin(tauri_plugin_shell::init())
    .plugin(tauri_plugin_deep_link::init())
    // ...
}
```

## 服务器设置( Better Auth 后端)

```ts
import { betterAuth } from "better-auth";
import { tauri } from "@dreamshive/better-auth-tauri";

export const auth = betterAuth({
  // ... your existing config
  trustedOrigins: ["yourapp://"],
  plugins: [
    tauri(),
    // ... your other plugins
  ],
});
```

服务器插件 :

1.  重映射 `tauri-origin` → `origin` 因此 CSRF / 信任起源检查接受自定义方案.
2.  重写 `x-tauri-cookie` → `Cookie` 因此客户端走私的会话饼干在Better Auth中可见.
3.  附录 `?cookie=<Set-Cookie>` 用于 OAuth 重定向 URL , 瞄准自定义方案, 因此 Tauri app 可以连接 cookie 罐 .
4.  显示 a `/tauri-authorization-proxy` 植入 OAuth 的终点 `state` 在系统浏览器的罐子中饼干在重定向到提供者之前(防止回调状态不匹配).

代理是一个公开的端点,因此它只对一个真正的登录出产的请求采取行动. 它仅在配置于 HTTPS 的供应商的授权来源上重定向到 HTTPS URL `socialProviders` 或者说 `genericOAuth`,它只表示一个 `state` 此服务器已发布但尚未过期 。 其他的都一样 `400` 没有饼干 没有方向 SSO 身份提供者(`/sign-in/sso`)不通过代理路由.

如果您在 0.1.5 启用服务器插件前运行了版本, 请旋转 `BETTER_AUTH_SECRET`: 这些版本签名 `state` 它们在定点前的签名一直有效 直到秘密改变.

### (简体中文)

您的认证服务器的 CORS 配置必须允许此插件发送的自定义头 :

```ts
cors({
  origin: [/* your frontend origins */, "yourapp://"],
  credentials: true,
  allowedHeaders: [
    "Content-Type",
    "Authorization",
    "Cookie",
    "tauri-origin",
    "x-tauri-cookie",
    "x-skip-oauth-proxy",
  ],
})
```

## 客户端设置

```ts
import { createAuthClient } from "better-auth/vue"; // or /react, /solid, etc.
import { tauriClient } from "@dreamshive/better-auth-tauri/client";
import { fetch as tauriFetch } from "@tauri-apps/plugin-http";
import { isTauri } from "@tauri-apps/api/core";

export const authClient = createAuthClient({
  baseURL: "https://auth.example.com",
  fetchOptions: {
    // Always use tauriFetch in Tauri — the webview's native fetch() drops
    // our smuggled headers and hits CORS on custom schemes.
    customFetchImpl: (...args) =>
      isTauri() ? tauriFetch(...args) : fetch(...args),
  },
  plugins: [
    tauriClient({
      scheme: "yourapp",        // must match tauri.conf.json
      cookiePrefix: "yourapp",  // must match your server's cookie prefix
      storage: {
        // See "Secure storage" below — localStorage is dev-only.
        getItem: (k) => localStorage.getItem(k),
        setItem: (k, v) => localStorage.setItem(k, v),
      },
    }),
  ],
});
```

然后通常使用更好的 Auth :

```ts
await authClient.signIn.social({
  provider: "github",
  callbackURL: "/", // auto-rewritten to yourapp:///
});
```

插件从那里取出 .

## 安全存储

`localStorage` 实值 **不适合生产** ——您 Tauri 网页视图中的任何 XSS都可以直接读取.

生产,退后 `storage` 选项。 选项, 按工程学排名 :

### 备选办法A——OS键链(建议)

展览 `keyring-rs` 通过定制 Tauri 命令。 每个平台的本土秘密商店(Apple Keychain,Windows Creditic Manager,特务在Linux).

```bash
cd src-tauri
cargo add keyring --features apple-native,windows-native,linux-native-sync-persistent
```

```rust
// src-tauri/src/keyring.rs
use keyring::Entry;

#[tauri::command]
pub fn keyring_get(service: String, key: String) -> Result<Option<String>, String> {
  let entry = Entry::new(&service, &key).map_err(|e| e.to_string())?;
  match entry.get_password() {
    Ok(v) => Ok(Some(v)),
    Err(keyring::Error::NoEntry) => Ok(None),
    Err(e) => Err(e.to_string()),
  }
}

#[tauri::command]
pub fn keyring_set(service: String, key: String, value: String) -> Result<(), String> {
  let entry = Entry::new(&service, &key).map_err(|e| e.to_string())?;
  entry.set_password(&value).map_err(|e| e.to_string())
}
```

登记时间 `lib.rs`数字 :

```rust
mod keyring;

tauri::Builder::default()
  .invoke_handler(tauri::generate_handler![
    keyring::keyring_get,
    keyring::keyring_set,
  ])
```

在您的客户端存储适配器中:

```ts
import { invoke } from "@tauri-apps/api/core";
const SERVICE = "com.yourapp.session";

const keyringStorage = {
  getItem: (key: string) => invoke<string | null>("keyring_get", { service: SERVICE, key }),
  setItem: (key: string, value: string) => invoke("keyring_set", { service: SERVICE, key, value }),
};
```

### 备选案文B - `tauri-plugin-stronghold`

官方Tauri加密金库(IOTA Stronghold). 需要应用程序提供的主密码句 .

### 备选案文C- `@tauri-apps/plugin-store`

上盘JSON,没有加密,而是住在Tauri IPC后方(无法从 `document.localStorage`) (中文(简体) ). 边际改善 `localStorage`。 。 。 .

## 选项

### `tauri(options?)` — 服务器插件

| 选项 | 默认 | 说明 |
| --- | --- | --- |
| `disableOriginOverride` | `false` | 别乱画 `tauri-origin` → `origin`。 。 。 . |

### `tauriClient(options)` ——客户端插件

| 选项 | 默认 | 说明 |
| --- | --- | --- |
| `scheme` | ——(需要) | 自定义 URI 方案注册于 `tauri.conf.json`。 。 。 . |
| `storage` | ——(需要) | 密钥/值存储适配器. 支持自动同步方法 . |
| `storagePrefix` | `"better-auth"` | 存储密钥的前缀 . |
| `cookiePrefix` | `"better-auth"` | 服务器 cookie-name 前缀( s). |
| `disableCache` | `false` | 禁用本地语言 `/get-session` 响应缓存. |
| `refetchOnWindowFocus` | `true` | 当 Tauri 窗口重起焦点时, 反射会话 . |
| `refetchOnReconnect` | `true` | 网络恢复上线时的回溯会话 . |

## 出口

```ts
// Server
import { tauri, tauriAuthorizationProxy } from "@dreamshive/better-auth-tauri";

// Client
import {
  tauriClient,
  setupTauriFocusManager,   // manual wiring if you disabled auto-setup
  setupTauriOnlineManager,
} from "@dreamshive/better-auth-tauri/client";
```

## macOS dev 工作流程

MacOS上的深链接URI计划通过应用程序在发射服务注册 `.app` 捆绑 `Info.plist`。 。 。 . **`tauri dev` 不产生捆绑** ——它运行一个生的二进制,macOS无法引导深层链接到.

针对macOS上深链插件开发的官方 Tauri 指导 :

```bash
# Build once (also run after any Rust/plugin/capability change)
bun tauri build --debug
# Open the bundle so Launch Services indexes it
open src-tauri/target/debug/bundle/macos/your-app.app
```

前端 (Vue/React/Svelte) HMR 可以通过已建成的应用程序运行, 如果您指向的话 `frontendDist` 在您的 dev 服务器上:

```json
// src-tauri/tauri.dev.conf.json
{
  "$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
  "build": {
    "frontendDist": "http://localhost:3000",
    "beforeBuildCommand": ""
  }
}
```

```bash
bun tauri build --debug --config src-tauri/tauri.dev.conf.json
```

## 已知的限制

-   **macOS dev 循环需要捆绑** (见上文)。 Windows和Linux没有这种摩擦.
-   **劫持计划** ——任何应用程序都可以注册为您的自定义计划的操作员. 具有有意义的攻击表面的生产应用软件应当考虑通用链接(macOS)或App链接(Android等同).
-   **存储是呼叫者的责任.** 此插件不会捆绑一个安全的存储原始; 您提供适配器 .
-   **没有安保部门支助.** Tauri apps 仅限客户端.

## 与 `@better-auth/expo`

Authority流量的地物对地平价,外加两个Tauri特异性加法:

| 特性 | 博览 | Tauri( 这个) |
| --- | --- | --- |
| OAuth 通过系统浏览器 | ✅ | ✅ |
| Cookie 桥通过 URL 查询参数 | ✅ | ✅ |
| 状态的授权代理端点 | ✅ | ✅ |
| 重定向到策略调用重写 | ✅ | ✅ |
| 注册本地清理 | ✅ | ✅ |
| 第三方饼干过滤器 | ✅ | ✅ |
| 焦点调试管理器 | QQ (响应查询) | QQ (通知更好的 Auth 会话信号) |
| 在线 reach 管理器 | QQ (响应查询) | QQ (通知更好的 Auth 会话信号) |
| **`x-tauri-cookie` 走私** | —— 说 | 需要( 浏览器禁止 `Cookie`(中文(简体) ) |
| **`disableRedirect: true` 注射** | —— 说 | 需要(浏览器有) `window.location`(中文(简体) ) |

## 许可证

麻省理工学院 [鲁利·阿尔迪亚斯亚](https://github.com/DreamsHive)

## 常见问题

### @dreamshive/better-auth-tauri 是什么？

Tauri桌面应用的更好的Auth插件——通过系统浏览器处理OAuth,使用深链接回调,通过URL进行cookie接通,并安全地存储符钩\.

### 如何安装 @dreamshive/better-auth-tauri？

在项目目录运行 npm install @dreamshive/better-auth-tauri，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：better-auth（^1\.7\.16）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @dreamshive/better-auth-tauri 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @dreamshive/better-auth-tauri 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @dreamshive/better-auth-tauri 可以商用吗？

@dreamshive/better-auth-tauri 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @dreamshive/better-auth-tauri 的下载量有多少？

根据 npm 官方下载统计，@dreamshive/better-auth-tauri 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,064 次，日均约 102 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @dreamshive/better-auth-tauri 还在维护吗？

最新版本 0\.1\.5 发布于 2026/11/10（3 天前）；至今共发布 6 个版本，其中过去 12 个月发布了 6 个；首次发布于 2026/04/20。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

