跳转到内容

Deep Link 协议与跨平台注册

Deep Link 协议与跨平台注册

学习目标

  • 理解 ccswitch:// URL 协议的格式与解析逻辑
  • 掌握三大平台的 Deep Link 注册方式差异
  • 了解 Deep Link 事件从 OS 到前端的事件传递链
  • 识别 URL 注入攻击的防护策略

项目实践

URL 协议格式

CC Switch 自定义协议:ccswitch://

URL 格式示例:

ccswitch://import-provider?app=claude&name=MyProvider&apiKey=sk-xxx&baseUrl=https://api.example.com

解析结果(src-tauri/src/deeplink/):

DeepLinkImportRequest {
resource: "provider" | "mcp" | "skill" | "prompt",
app: "claude" | "codex" | "gemini" | ...,
name: "供应商名称",
data: { /* 解析后的参数映射 */ }
}

跨平台注册

tauri-plugin-deep-link 插件负责在各平台注册 ccswitch:// 协议:

macOS

通过 Info.plist 注册 CFBundleURLTypes

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>CC Switch</string>
<key>CFBundleURLSchemes</key>
<array>
<string>ccswitch</string>
</array>
</dict>
</array>

URL 通过 RunEvent::Opened 事件传递(AppleEvent 机制)。

Windows

通过注册表注册协议:

HKEY_CLASSES_ROOT/ccswitch/
(Default) = "URL:CC Switch Protocol"
URL Protocol = ""
shell/open/command/
(Default) = "C:\Program Files\CC Switch\cc-switch.exe" "%1"

URL 通过命令行参数传递到 single_instance 回调。

Linux

通过 .desktop 文件注册:

[Desktop Entry]
Exec=cc-switch %u
MimeType=x-scheme-handler/ccswitch;

文件位置:~/.local/share/applications/cc-switch-handler.desktop

防覆盖机制:CC Switch 在注册前检查 .desktop 文件是否已存在,只有不存在时才创建:

let should_register = app.path().data_dir()
.map(|d| !d.join("applications/cc-switch-handler.desktop").exists())
.unwrap_or(true);

这避免覆盖用户的自定义修改。

URL 处理事件链

Deep Link URL 到达应用后的处理链:

关键函数handle_deeplink_url()lib.rs 中实现:

  1. 验证 URL 是否以 ccswitch:// 开头
  2. 记录日志(URL 中的敏感信息被脱敏:redact_url_for_log
  3. 调用 parse_deeplink_url() 解析
  4. 解析成功 → emit deeplink-import 事件 → 前端显示导入对话框
  5. 解析失败 → emit deeplink-error 事件 → 前端显示错误

URL 日志脱敏

Deep Link URL 中可能包含 API Key 等敏感信息。CC Switch 在日志中自动脱敏:

fn redact_url_for_log(url_str: &str) -> String {
// 保留: scheme + host + path + query parameter keys
// 移除: query parameter values
// 示例: https://api.example.com/v1?key=[redacted]&model=gpt-4
}

这样日志中可以看到请求的目标地址和参数名,但看不到实际值。

当应用处于轻量模式(lightweight_mode,资源受限环境下的简化 UI)时,收到 Deep Link URL 会:

  1. 退出轻量模式(exit_lightweight_mode
  2. 重建完整窗口
  3. 处理 Deep Link 请求

这确保 Deep Link 导入功能在轻量模式下也能正常工作。


问题与规避

陷阱 1:URL 注入攻击

问题:恶意网站可能通过 <a href="ccswitch://..."> 链接触发 CC Switch 执行危险操作。

CC Switch 的解决方案

  • Deep Link URL 只触发”导入”操作(导入供应商、MCP 等),不执行”删除”或”切换”等破坏性操作
  • 导入操作需要用户在 UI 中确认
  • URL 中不包含敏感操作所需的完整参数(如完整的 API Key 可能被浏览器历史泄漏)

陷阱 2:Linux 下 .desktop 文件注册失败

问题:某些 Linux 发行版的 .desktop 文件目录路径不同(如 Flatpak 环境)。

CC Switch 的解决方案

  • 使用 Tauri 的 app.path().data_dir() 获取正确的数据目录
  • 注册失败时记录警告日志但不中断应用
  • 用户仍可手动打开应用并使用其他功能

陷阱 3:Windows 下 URL 被浏览器拦截

问题:部分浏览器可能不识别 ccswitch:// 协议,点击链接时无反应。

规避:在文档中提示用户”首次点击时需在浏览器中确认打开 CC Switch”。这是操作系统级别的行为,应用无法控制。


设计取舍

方案优势劣势
Deep Link URL浏览器可直接触发,无需后端需要各平台注册协议
本地 API 服务器不需要注册协议需要额外的端口管理、CORS 配置
文件导入最简单需要用户手动下载文件再导入

Deep Link 的核心优势是零摩擦导入——用户在网页上点击一个链接,CC Switch 自动弹出并显示导入预览。


参考来源