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 %uMimeType=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 中实现:
- 验证 URL 是否以
ccswitch://开头 - 记录日志(URL 中的敏感信息被脱敏:
redact_url_for_log) - 调用
parse_deeplink_url()解析 - 解析成功 → emit
deeplink-import事件 → 前端显示导入对话框 - 解析失败 → 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}这样日志中可以看到请求的目标地址和参数名,但看不到实际值。
轻量模式退出与 Deep Link
当应用处于轻量模式(lightweight_mode,资源受限环境下的简化 UI)时,收到 Deep Link URL 会:
- 退出轻量模式(
exit_lightweight_mode) - 重建完整窗口
- 处理 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 vs API
| 方案 | 优势 | 劣势 |
|---|---|---|
| Deep Link URL | 浏览器可直接触发,无需后端 | 需要各平台注册协议 |
| 本地 API 服务器 | 不需要注册协议 | 需要额外的端口管理、CORS 配置 |
| 文件导入 | 最简单 | 需要用户手动下载文件再导入 |
Deep Link 的核心优势是零摩擦导入——用户在网页上点击一个链接,CC Switch 自动弹出并显示导入预览。
参考来源
- Tauri Deep Link Plugin. https://tauri.app/plugin/deep-link/
- macOS URL Scheme 文档. https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app
- Linux MIME 注册. https://specifications.freedesktop.org/desktop-entry-spec/