swift cookie

2021-08-25  本文已影响0人  周无恋

由于wkWebView的隐私政策,对于cookie的限制颇多,个人建议

尽量不要用cookie 传递数据

保存网络请求的cookies,并存储到UserDefaults中

//保存COOKIES
static func saveCookies(for urlStr: String){
    if let url = URL(string: urlStr){
        if let cookies = HTTPCookieStorage.shared.cookies(for: url){
            var JSESSIONID = ""
            for cookie in cookies {
                    if cookie.name == "SESSION"{
                    JSESSIONID = cookie.value
                    break
                }
            }
            if JSESSIONID.count > 0 {
                let defaults = UserDefaults.standard
                defaults.set(JSESSIONID, forKey: "SESSIONID")
                defaults.synchronize()
            }
        }
    }
}
//如果是登录成功一般还需要
func saveLoginCookie(_ urlStr: String){
    let str = HOST_API + urlStr
    if let url = URL(string: str) {
       let cookies = HTTPCookieStorage.shared.cookies(for: url)
        //将cookies转换成Data
        let data = NSKeyedArchiver.archivedData(withRootObject: cookies as Any)
        //将data存储到userDefaults中
        UserDefaults.standard.set(data, forKey: HXQUserCookie)
    }
}

发起网络请求时,获取已经保存的cookies

static func getCookies(){
    let defaults = UserDefaults.standard
    let JSESSIONID = defaults.value(forKey: "SESSIONID") as? String
    var TOKEN = ""
    //登录成功TOKEN
    if let cookieData = defaults.value(forKey: HXQUserCookie) as? Data{
        if cookieData.count > 0{
            if let cookies = NSKeyedUnarchiver.unarchiveObject(with: cookieData) as? Array<HTTPCookie>{
                for cookie in cookies {
                    if cookie.name == "TOKEN"{
                        TOKEN = cookie.value
                        break
                    }
                }
            }
        }
    }
    
    if TOKEN.count > 0 && JSESSIONID != nil {
        
        if let sessionCookie = HTTPCookie(properties: creatHTTPCookie("SESSIONID", vlaue: JSESSIONID!)) {
            HTTPCookieStorage.shared.setCookie(sessionCookie)
        }
        
        if let tokenCookie = HTTPCookie(properties: creatHTTPCookie("TOKEN", vlaue: TOKEN)) {
            HTTPCookieStorage.shared.setCookie(tokenCookie)
        }
    }
}

static func creatHTTPCookie(_ key: String, vlaue: String) -> [HTTPCookiePropertyKey : Any] {
    // 定义一个可变字典存放cookie键值对
    var properties: [HTTPCookiePropertyKey : Any] = [:]
    properties[.name] = key
    properties[.path] = "/"
    properties[.value] = vlaue
    properties[.secure] = true
    #if DEBUG
    let domain = "cs.hxquan.cn"
    #else
    let domain = "m.hxquan.cn"
    #endif
    properties[.domain] = domain
    properties[.version] = 0
    return properties
}

这里创建cookie的时候需要特别注意,swift中cookie创建 HTTPCookie(properties: [HTTPCookiePropertyKey : Any]),需要 [HTTPCookiePropertyKey : Any]这种格式的字典,不像oc中那么直接的键值对,cookie中的name,path,value,secure,domain,version等字段都必须要有,oc中不需要。

移除保存的cookies

static func removeCookies(){
    if let cookies = HTTPCookieStorage.shared.cookies{
        //移除cookies
        for cookie in cookies {
            HTTPCookieStorage.shared.deleteCookie(cookie)
        }
    }
    //移除userDefaults数据
    let defaults = UserDefaults.standard
    defaults.removeObject(forKey: HXQUserCookie)
    defaults.removeObject(forKey: "SESSIONID")
    defaults.synchronize()
}

针对wkwebView的cookie的操作:
wkwebView在访问的时候如果需要记录用户的操作,也需要传入cookie,但是wkWebView不能直接通过HTTPCookieStorage来访问cookie,需要把cookie存放在WKUserScript中

lazy var webView: WKWebView = {[weak self] in
    let config = WKWebViewConfiguration()
    config.userContentController = WKUserContentController()
    //允许内嵌video播放
    config.allowsInlineMediaPlayback = true
    config.userContentController.add(WeakScriptMessageDelegate(scriptDelegate: self!), name: HxqWebHandleName)
    
    let defaults = UserDefaults.standard
    var cookieDict = [String:String]()
    if let SESSIONID = defaults.value(forKey: "SESSIONID") as? String{
        cookieDict["SESSIONID"] = SESSIONID
    }
    if let cookiesData = defaults.value(forKey: HXQUserCookie) as? Data{
        if  let cookies = NSKeyedUnarchiver.unarchiveObject(with: cookiesData) as? Array<HTTPCookie> {
            for cookie in cookies{
                if cookie.name == "TOKEN"{
                    cookieDict["SESSIONID"] = cookie.value
                    break
                }
            }
        }
    }
    if cookieDict.keys.count == 2{
        let cookieScript = WKUserScript(source: "document.cookie = 'TOKEN=\(cookieDict["TOKEN"]!);path=/';document.cookie = 'SESSIONID=\(cookieDict["SESSIONID"]!);path=/'", injectionTime: .atDocumentStart, forMainFrameOnly: false)
        config.userContentController.addUserScript(cookieScript)
    }
    let webView = WKWebView(frame: .zero, configuration: config)
    webView.uiDelegate = self
    webView.navigationDelegate = self
    return webView
}()

这里也有一个地方需要注意的document.cookie = 'TOKEN=(cookieDict["TOKEN"]!);path=/'',这里的path=/一定要加上,当初调试的时候因为这个问题花了很长时间才找到原因

上一篇下一篇

猜你喜欢

热点阅读