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

PWA转iOS原生应用:WebView认证用户关联Firebase Device Token问题

解决方案

针对你遇到的FCM令牌与WebView中认证用户关联的问题,这里提供两种安全可行的方案:

方案一:将FCM令牌注入WebView,通过前端JS提交后端(推荐)

这种方案复用你PWA中原有的令牌关联逻辑,只需在Swift端将令牌注入WebView,由前端利用已有的用户会话提交到后端。

步骤1:Swift端获取并注入FCM令牌

在WebView加载完成后,验证页面域名属于你的PWA,然后注入JS代码调用前端全局函数:

import WebKit
import FirebaseMessaging

class ViewController: UIViewController, WKNavigationDelegate, MessagingDelegate {
    var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 初始化WebView
        let config = WKWebViewConfiguration()
        webView = WKWebView(frame: view.bounds, configuration: config)
        webView.navigationDelegate = self
        view.addSubview(webView)
        
        // 监听FCM令牌刷新
        Messaging.messaging().delegate = self
        // 获取初始令牌
        Messaging.messaging().token { token, error in
            if let token = token {
                UserDefaults.standard.set(token, forKey: "FCMToken")
            }
        }
    }

    // WebView加载完成后注入令牌
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        guard let fcmToken = UserDefaults.standard.string(forKey: "FCMToken"),
              let url = webView.url, url.host == "your-pwa-domain.com" else { return }
        
        let injectJS = "window.registerFCMToken('\(fcmToken)');"
        webView.evaluateJavaScript(injectJS) { _, error in
            error.map { print("注入令牌失败: \($0.localizedDescription)") }
        }
    }

    // 令牌刷新时重新注入
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        guard let token = fcmToken else { return }
        UserDefaults.standard.set(token, forKey: "FCMToken")
        
        if let currentUrl = webView?.url, currentUrl.host == "your-pwa-domain.com" {
            let injectJS = "window.registerFCMToken('\(token)');"
            webView.evaluateJavaScript(injectJS, completionHandler: nil)
        }
    }
}

步骤2:前端PWA中接收令牌并提交后端

在你的PWA JS代码中定义全局函数,利用已认证的会话(Cookie)将令牌提交到后端:

// 全局函数,接收Swift注入的FCM令牌
window.registerFCMToken = function(token) {
    // 复用原有PWA的令牌提交逻辑,credentials: 'include'会自动带上用户会话Cookie
    fetch('/api/user/fcm-token', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ token }),
        credentials: 'include'
    }).catch(err => console.error('令牌提交失败:', err));
};

方案二:Swift端获取WebView会话信息,直接调用后端API关联令牌

如果不想修改前端代码,可以在Swift端获取WebView中的用户会话Cookie,直接调用后端API完成令牌与用户的关联。

步骤1:Swift获取WebView会话Cookie

func getSessionCookie(completion: @escaping (String?) -> Void) {
    guard let pwaUrl = URL(string: "https://your-pwa-domain.com") else {
        completion(nil)
        return
    }
    
    WKWebsiteDataStore.default().httpCookieStore.getAllCookies { cookies in
        // 替换成你后端使用的会话Cookie名称
        let sessionCookie = cookies.first { $0.name == "user_session_id" }
        completion(sessionCookie?.value)
    }
}

步骤2:调用后端API关联令牌

在用户登录完成后(比如WebView跳转到登录成功页面时),执行关联逻辑:

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    guard let url = webView.url, url.path == "/login/success" else { return }
    
    getSessionCookie { sessionId in
        guard let sessionId = sessionId,
              let fcmToken = UserDefaults.standard.string(forKey: "FCMToken") else { return }
        
        let apiUrl = URL(string: "https://your-api-domain.com/api/fcm/associate")!
        var request = URLRequest(url: apiUrl)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        // 根据后端认证方式设置头,比如Cookie或Authorization
        request.setValue("user_session_id=\(sessionId)", forHTTPHeaderField: "Cookie")
        
        let body = ["token": fcmToken]
        request.httpBody = try? JSONSerialization.data(withJSONObject: body)
        
        URLSession.shared.dataTask(with: request) { _, _, error in
            error.map { print("关联失败: \($0.localizedDescription)") }
        }.resume()
    }
}

安全注意事项

  • 无论哪种方案,都要验证WebView访问的域名,防止令牌注入到恶意页面
  • 后端要校验提交请求的合法性,确保会话有效且属于当前用户
  • FCM令牌可能会定期刷新,务必监听令牌更新事件并重新关联

内容的提问来源于stack exchange,提问作者O'Niel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:04:58