记一次 Universal Links 使用与APP微信登录及总结 📅 2026/7/1 15:35:51 文章目录前言需求环境含义与作用1.1 什么是 Universal Links1.2 核心用途1.3 与 URL Scheme 对比apple-app-site-association 文件2.1 文件说明2.2 放置位置2.3 文件内容示例2.4 服务端要求注意不要求必须搭建web服务器可以放到CDN中哦~完整配置方法3.1 服务端部署 AASA 文件3.2 Apple Developer 配置3.3 Xcode 配置3.4 代码配置3.5 微信开放平台配置作用流程4.1 Apple CDN 验证流程App 安装时4.2 用户点击链接流程4.3 微信登录回调流程注意事项5.1 三处配置必须保持一致5.2 修改时的推荐操作顺序5.3 版本兼容策略5.4 常见踩坑点5.5 用户禁用场景验证与调试6.1 验证检查清单6.2 验证命令为什么 URL Scheme 会被盗用URL Scheme 的工作方式具体攻击场景为什么 Universal Links 能证明身份核心原理用 HTTPS 域名所有权做背书和 URL Scheme 的对比黑产能仿冒 Universal Links 吗总结前言又月底了总得再凑出一篇不是在AI大行其道的时代手搓文章可能又要变成古法写作不久将被评为非遗传承人了哈哈哈不过不管AI怎么发展总会给手搓留下一席之地就像现在拍张已经非常方便了但是绘画依旧有自己市场一样AI可以写主要部分但是认为的记录还是有一些精华点的不然满屏的AI味实在让人看不下去昨晚看到一个观点挺有意思之前总说加密货币没有意义浪费电但是在AI横行的时代在难辨真假的时代消耗能源镌刻进资源的方式或许本身就是一种意义就好似密码学中引入工作负载来破解难度一样所以如果把加密大模型绑定到一起那不是电上加电变成电的平方了嘛。跑远了说回本文重点Universal Links苹果的东东主要是最近APP接入微信登录需要配置这东西实现登录后打开APP的目的。需求环境Apple App Site Association 配置完全指南适用于 iOS 13 / 微信 OpenSDK 1.8.6含义与作用1.1 什么是 Universal LinksUniversal Links通用链接是 Apple 在 iOS 9 推出的机制通过标准 HTTPS 链接直接打开 App建立网站域名与 iOS/macOS App 之间的信任关系。1.2 核心用途通用链接点击网页链接直接打开 App无需跳转浏览器App 未安装时自动降级到 SafariHandoff / Shared Web Credentials跨设备接力Safari 密码可在 App 内自动填充第三方 SDK 回调微信等 SDK 用于 App 间相互唤起时的安全校验通道1.3 与 URL Scheme 对比对比项URL SchemeUniversal Links安全性低可被其他 App 劫持高Apple CDN 校验无法劫持App 未安装报错或无响应自动降级到 Safari配置复杂度简单需要服务端 客户端协同iOS 版本iOS 3iOS 9微信 SDK旧版已废弃SDK 1.8.6 强制要求apple-app-site-association 文件2.1 文件说明纯文本 JSON 格式文件名固定为apple-app-site-association无任何后缀必须部署在 HTTPS 域名下不能有重定向2.2 放置位置Apple 按以下顺序检查推荐第一个https://example.com/.well-known/apple-app-site-association ← 推荐 https://example.com/apple-app-site-association2.3 文件内容示例{applinks:{apps:[],details:[{appID:TEAMID.com.example.myapp,paths:[/app/*]}]}}这面这种使用或者下面这种推荐格式{applinks:{details:[{appIDs:[TEAMID.com.example.myapp],components:[{/:/app/*},{/:/product/*},{/:/user/*/profile}]}]},webcredentials:{apps:[TEAMID.com.example.myapp]}}2.4 服务端要求要求项说明协议必须 HTTPS证书有效不接受 HTTP重定向不能有重定向Apple CDN 不跟随跳转Content-Type返回application/json文件名apple-app-site-association无后缀path 通配符末尾必须加/*微信等 SDK 会在路径后拼接参数appID 格式TeamID BundleID如ABCDE12345.com.example.myapp注意不要求必须搭建web服务器可以放到CDN中哦~完整配置方法3.1 服务端部署 AASA 文件确保 path 加通配符微信会在 Universal Link 末尾拼接路径和参数components:[{/:/app/*}]3.2 Apple Developer 配置登录 Apple Developer → Identifiers找到对应 App开启Associated Domains能力如使用手动 Profile需重新生成描述文件3.3 Xcode 配置在 Signing Capabilities 添加 Associated Domainsapplinks:example.com applinks:www.example.com applinks:example.com?modedeveloper // 开发调试模式3.4 代码配置SDK 注册以微信为例WXApi.registerApp(wx1234567890abcdef,universalLink:https://example.com/app/)处理回调 — SceneDelegateiOS 13funcscene(_scene:UIScene,continueuserActivity:NSUserActivity){guarduserActivity.activityTypeNSUserActivityTypeBrowsingWeb,leturluserActivity.webpageURLelse{return}handleUniversalLink(url)}处理回调 — AppDelegate兼容旧版funcapplication(_application:UIApplication,continueuserActivity:NSUserActivity,...)-Bool{guardleturluserActivity.webpageURLelse{returnfalse}handleUniversalLink(url)returntrue}3.5 微信开放平台配置登录 open.weixin.qq.com → 管理中心 → 移动应用找到对应应用 → 开发信息 → 修改在 iOS 应用 → Universal Links 中填入https://example.com/app/注意结尾必须有 /作用流程4.1 Apple CDN 验证流程App 安装时App 安装 → iOS 读取 Entitlement 中的 Associated Domains → Apple CDN 请求 AASA 文件 https://app-site-association.cdn-apple.com/a/v1/example.com → 验证 appIDs 中的 TeamID BundleID 与 App 匹配 → 缓存路径规则到设备 → Universal Links 生效 验证失败 → 链接只在浏览器打开Apple 通过自己的 CDN 代理请求不是设备直连服务器更新 AASA 后最长延迟24~48 小时生效。4.2 用户点击链接流程用户点击 https://example.com/app/xxx → iOS 检查本地缓存路径规则 → 路径匹配 ├── 是 → App 已安装 │ ├── 是 → 直接打开 App触发 continueUserActivity 回调 │ └── 否 → Safari 打开可配置 Smart App Banner 引导下载 └── 否 → Safari 打开4.3 微信登录回调流程你的 App 调用微信 SDK 发起登录 → 跳转微信 App用户授权 → 微信通过 Universal Link 唤起你的 App 在路径后拼接 code、state 等参数 → 触发 continueUserActivity 回调 → WXApi.handleOpenUniversalLink 解析登录结果注意事项5.1 三处配置必须保持一致微信开放平台后台 https://example.com/app/ ↕ 必须相同 SDK 注册代码 universalLink: https://example.com/app/ ↕ path 必须能覆盖 AASA 文件 { /: /app/* }修改任意一处必须同时更新其他两处否则校验失败。5.2 修改时的推荐操作顺序先更新服务端 AASA 文件并验证可访问更新微信开放平台后台配置更新代码中 SDK 注册的universalLink参数发版5.3 版本兼容策略修改域名或路径时新旧路径应在 AASA 中同时保留一段时间待旧版用户自然升级后再移除旧路径。5.4 常见踩坑点问题原因解决方法Universal Links 不生效AASA 未正确部署或有重定向curl 验证文件可访问检查 Content-Type微信授权出现二次确认弹窗Universal Link 校验失败检查三处配置是否一致path 匹配失败末尾缺少通配符/*改为/app/*格式appID 不匹配TeamID 或 BundleID 填错在 Apple Developer 后台核实 TeamID修改后未生效AASA 只在首次安装时下载删除 App 重新安装WKWebView 内链接不触发WKWebView 不自动触发 UL手动拦截decidePolicyFor处理Apple CDN 延迟Apple 通过 CDN 代理非实时更新后最长 24~48 小时生效企业签名证书失效部分企业证书不具备 UL 能力使用开发签名证书调试5.5 用户禁用场景用户长按链接选择「在 Safari 中打开」后该域名 Universal Links 被临时禁用需在 Safari 中点击顶部 Banner 重新启用。验证与调试6.1 验证检查清单检查项正确值AASA Content-Typeapplication/jsonHTTPS 证书有效无自签名无重定向Team ID与 Apple Developer 后台一致Bundle ID与 Xcode 项目一致path 末尾必须有通配符/*Entitlement 格式applinks:前缀无https://三处 URL 一致性微信后台 SDK 注册 AASA path 覆盖6.2 验证命令# 验证 AASA 可访问curl-Ihttps://example.com/.well-known/apple-app-site-association# 查看 Apple CDN 缓存内容curlhttps://app-site-association.cdn-apple.com/a/v1/example.com# 模拟器测试链接xcrun simctl openurl bootedhttps://example.com/app/test在线验证工具https://branch.io/resources/aasa-validator/为什么 URL Scheme 会被盗用URL Scheme 的工作方式任何 App 都可以在Info.plist里声明自己支持某个 Scheme!-- 恶意 App 的 Info.plist --keyCFBundleURLSchemes/keyarraystringmybank/string!-- 和你的银行 App 一模一样 --/arrayiOS不做任何唯一性校验两个 App 声明同一个 Scheme 完全合法。当系统收到mybank://pay?amount100时如果两个 App 都安装了行为是不确定的通常后安装的会覆盖。具体攻击场景正常流程 微信 → 调用 mybank://pay → 打开你的银行 App → 完成支付 被盗用后 微信 → 调用 mybank://pay → 打开黑产仿冒的银行 App ↓ 展示假支付页面 或静默收集参数 或返回假成功给微信黑产只需要上架一个仿冒 App声明相同的 Scheme就能劫持所有通过该 Scheme 发起的跳转。用户完全无感知。为什么 Universal Links 能证明身份核心原理用 HTTPS 域名所有权做背书Universal Links 的信任链是这样的你能在 example.com 放文件 ↓ 说明你是 example.com 的所有者 ↓ 你在 AASA 文件里声明了某个 AppID ↓ 说明该 App 是你发布的 ↓ iOS 信任这个 App 处理 example.com 的链接关键在于往域名根目录放文件这件事只有域名所有者才能做到。和 URL Scheme 的对比URL SchemeUniversal Links声明方式App 本地 Info.plist 自己写服务器上的 AASA 文件谁能声明任何人无需审核只有域名所有者校验时机运行时iOS 不校验唯一性App 安装时Apple CDN 主动验证仿冒成本极低改个 plist 即可极高需要控制对方的域名服务器黑产能仿冒 Universal Links 吗假设黑产想劫持https://example.com/app/的跳转方案一伪造 AASA 文件需要在example.com上放文件但他们没有example.com的控制权❌ 无法实现方案二自己买个域名注册examp1e.com部署 AASA但链接变成了https://examp1e.com/app/不是原来的域名用户或调用方看 URL 就能发现异常❌ 无法劫持原链接方案三在 App 里声明相同的 Universal LinkUniversal Link 不是 App 声明的是服务器声明的App 里只有applinks:example.com的 EntitlementApple CDN 会去example.com验证AASA 里没有黑产的 AppID❌ 验证直接失败总结URL Scheme 是 App自己说自己是谁没有人核实Universal Links 是域名服务器替 App 担保而域名所有权由 HTTPS 证书 DNS 保证第三方无法伪造。APP配置微信登后回调时微信开放平台后台、SDK 注册代码、AASA 文件 配置必须一致https://example.com/app/apple-app-site-association不是必须放在web服务的中访问也可以放到CDN中只要能证明域名所有全就行 反爬链接请勿点击原地爆炸概不负责小孩子玩游戏才是真情流露随心所欲喜欢就是喜欢不喜欢就是不喜欢而大人玩游戏总喜欢斤斤计较精于算计看似“聪明伶俐但已经失去本心。