You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS类原生PWA的CAS认证流程异常:跳转Safari并重复打开页面

iOS Swift WebView封装PWA的CAS SSO认证窗口跳转问题

问题详情

我开发的Web应用基于外部CAS服务器实现SSO,认证流程为:

  • 访问myapp.com
  • 跳转至whereareyoufrom.com/form
  • 跳转至iamfromhere.com/login完成登录
  • 最终返回myapp.com

Android端通过PWABuilder封装的PWA完全正常,但iOS端用Swift WebView原生封装时出现异常:

  • 能正常进入CAS登录页,但提交表单后会唤起Safari打开新窗口,且重复显示登录页
  • 再次提交登录信息后,会跳转到iamfromhere.com/home,而非应用内的myapp.com/home
  • 关闭Safari后,回到应用内的登录页

已尝试无效方案

  • 在WebView.swift中设置config.limitsNavigationsToAppBoundDomains = false
  • 在index.html中添加<meta name="apple-mobile-web-app-capable" content="yes">
  • 将所有外部域名添加到PWA的允许URL列表

当前状态(编辑补充)

把iamfromhere.com加入Settings.swift的authOrigins和Info.plist的WKAppBoundDomains后,认证流程可以正常走完,但仍会在Safari打开重复窗口。

解决思路

1. 拦截新窗口请求,在应用内WebView加载

实现WKUIDelegate的webView(_:createWebViewWith:for:windowFeatures:)方法,拦截WebView的新窗口创建请求,直接在当前WebView内加载目标URL,避免唤起Safari:

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
    // 拦截target="_blank"的跳转请求
    guard let url = navigationAction.request.url, navigationAction.targetFrame == nil else {
        return nil
    }
    webView.load(URLRequest(url: url))
    return nil
}

注意要给WebView设置uiDelegate = self。

2. 移除CAS页面的target="_blank"属性

检查CAS登录表单或跳转链接是否带有target="_blank",如果有,直接修改为target="_self";如果无法修改CAS页面代码,可在WebView加载时注入JS移除该属性:

document.addEventListener('DOMContentLoaded', () => {
    // 处理所有表单
    document.querySelectorAll('form').forEach(form => form.target = '_self');
    // 处理所有新窗口链接
    document.querySelectorAll('a[target="_blank"]').forEach(link => link.target = '_self');
});

通过WKUserScript将这段JS注入WebView:

let script = WKUserScript(source: jsCode, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
config.userContentController.addUserScript(script)

3. 完善WKAppBoundDomains配置

确保Info.plist中的WKAppBoundDomains包含所有跳转涉及的域名,格式为数组,每个域名不带协议头:

<key>WKAppBoundDomains</key>
<array>
    <string>myapp.com</string>
    <string>whereareyoufrom.com</string>
    <string>iamfromhere.com</string>
</array>

4. 检查WebView的导航代理逻辑

确认WKNavigationDelegate的webView(_:decidePolicyFor:decisionHandler:)方法中,没有错误地允许外部浏览器打开链接:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    // 确保所有跳转都在应用内WebView处理
    decisionHandler(.allow)
}

内容的提问来源于stack exchange,提问作者agatherc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:50:31