主要內(nèi)容:
- Cookie認(rèn)識(shí)
- NSHTTPCookie
- 六大特性
1. Cookie認(rèn)識(shí)
我們通過的服務(wù)器和客戶端進(jìn)行交互往往是通過https/http請(qǐng)求完成的麻敌,而這個(gè)協(xié)議是無連接的,但有時(shí)候我們的業(yè)務(wù)中需要實(shí)現(xiàn)多次請(qǐng)求是有一定關(guān)聯(lián)性的老充,所以就需要約定一個(gè)信息供客戶端和服務(wù)器端進(jìn)行識(shí)別,這里就是用到了Cookie和Session芝囤。
客戶端請(qǐng)求時(shí)攜帶上Cookie划煮,服務(wù)器端進(jìn)行識(shí)別,識(shí)別后就可以進(jìn)行處理吹截,Cookie中攜帶的最重要的信息就是SessionID厌处,這個(gè)ID就可以查詢到服務(wù)器端保存的Session鳖谈,Session中保存了大量的該用戶信息,識(shí)別后就可以通過這些用戶信息對(duì)這個(gè)請(qǐng)求進(jìn)行處理阔涉。
在WKWebView中缆娃,我們能做的就是對(duì)Cookie進(jìn)行處理
作用:
- 會(huì)話狀態(tài)管理(如用戶登錄狀態(tài))
- 個(gè)性化設(shè)置(如用戶自定義設(shè)置、主題等)
- 瀏覽器行為跟蹤(如跟蹤分析用戶行為等)
1.1 過程
客戶端在一次給服務(wù)器端發(fā)送請(qǐng)求時(shí)瑰排,服務(wù)器端會(huì)生成一個(gè)Cookie返回給給客戶端贯要,客戶端在下一次請(qǐng)求發(fā)送時(shí)會(huì)攜帶上該Cookie,這樣后續(xù)請(qǐng)求就可以使用該Cookie來識(shí)別椭住。
- 創(chuàng)建Cookie崇渗,當(dāng)服務(wù)器收到HTTP請(qǐng)求時(shí),會(huì)創(chuàng)建一個(gè)Cookie,并在響應(yīng)頭中添加一個(gè)Set-Cookkie的選項(xiàng)宅广,附著上Cookie
- Cookie使用葫掉,客戶端在收到該Cookie后,在下次發(fā)送請(qǐng)求時(shí)乘碑,就會(huì)在Cookie選擇中攜帶上可以匹配的Cookie
- Cookie識(shí)別,服務(wù)器端在收到客戶端的請(qǐng)求后金拒,就會(huì)識(shí)別Cookie中的SessionID兽肤,以此查找Session,查找到后就可以使用Session信息來處理該請(qǐng)求
1.2 Cookie屬性認(rèn)識(shí)
Expires:
- 最長(zhǎng)有效時(shí)間绪抛,Cookie可以存活的時(shí)間(舊屬性)
- 如果沒有設(shè)置资铡,那么時(shí)間就是一個(gè)會(huì)話期,也就是如果客戶端被關(guān)掉幢码,則Cookie就會(huì)被移除
- 然而笤休,很多Web瀏覽器支持會(huì)話恢復(fù)功能,這個(gè)功能可以使瀏覽器保留所有的tab標(biāo)簽症副,然后在重新打開瀏覽器的時(shí)候?qū)⑵溥€原店雅。與此同時(shí),cookie 也會(huì)恢復(fù)贞铣,就跟從來沒有關(guān)閉瀏覽器一樣闹啦。
Max-Age:
- 最大存活時(shí)間
- 作用和Expires一樣,但是Max-Age是新屬性辕坝,如果同時(shí)存在窍奋,則優(yōu)先使用Max-Age
Domain:
- 該Cookie可被攜帶的主機(jī)名
- 也就是發(fā)送請(qǐng)求中如果給該主機(jī)發(fā)送,那么就可以選擇攜帶該Cookie(還需要判斷Path)
- 假如沒有指定酱畅,那么默認(rèn)值為當(dāng)前文檔訪問地址中的主機(jī)部分(但是不包含子域名)
- 與之前的規(guī)范不同的是琳袄,域名之前的點(diǎn)號(hào)會(huì)被忽略。
- 假如指定了域名纺酸,那么相當(dāng)于各個(gè)子域名也包含在內(nèi)了窖逗。(也就是這里如果寫了二級(jí)域名,那么二級(jí)域名相同的所有請(qǐng)求都可以攜帶該Cookie)
Path:
- 該Cookie需要被攜帶的路徑
- 也就是發(fā)送請(qǐng)求中如果給該地址發(fā)送餐蔬,那么就可以選擇使用該Cookie(還需要判斷主機(jī))
- 目錄的下級(jí)目錄也滿足匹配的條件滑负。(例如,如果 path=/docs用含,那么 "/docs", "/docs/Web/" 或者 "/docs/Web/HTTP" 都滿足匹配的條件)
Secure:
- 一個(gè)帶有安全屬性的 cookie 只有在請(qǐng)求使用SSL和HTTPS協(xié)議的時(shí)候才會(huì)被發(fā)送到服務(wù)器矮慕。
- 也就是說這個(gè)Cookie如果設(shè)置有Secure,那么這個(gè)請(qǐng)求只能是HTTPS協(xié)議啄骇,否則無法發(fā)送
HttpOnly:
- 設(shè)置了 HttpOnly 屬性的 cookie 不能使用 JavaScript 經(jīng)由 Document.cookie 屬性痴鳄、XMLHttpRequest 和 Request APIs 進(jìn)行訪問,以防范跨站腳本攻擊(XSS (en-US))缸夹。
SameSite:
- 允許服務(wù)器設(shè)定一則 cookie 不隨著跨域請(qǐng)求一起發(fā)送痪寻,這樣可以在一定程度上防范跨站請(qǐng)求偽造攻擊
2. NSHTTPCookie
2.1 創(chuàng)建Cookie
//使用提供的屬性創(chuàng)建并初始化一個(gè)HTTP cookie對(duì)象螺句。
- (nullable instancetype)initWithProperties:(NSDictionary<NSHTTPCookiePropertyKey, id> *)properties;
//用給定的cookie屬性初始化一個(gè)HTTP cookie對(duì)象。
+ (nullable NSHTTPCookie *)cookieWithProperties:(NSDictionary<NSHTTPCookiePropertyKey, id> *)properties;
為提供的URL創(chuàng)建一個(gè)與提供的響應(yīng)報(bào)頭字段對(duì)應(yīng)的HTTP cookie數(shù)組橡类。
+ cookiesWithResponseHeaderFields:forURL:
2.2 設(shè)置Cookie到請(qǐng)求頭
//將cookie數(shù)組轉(zhuǎn)換為報(bào)頭字段的字典蛇尚。
+ (NSDictionary<NSString *, NSString *> *)requestHeaderFieldsWithCookies:(NSArray<NSHTTPCookie *> *)cookies;
2.3 獲取Cookie主機(jī)屬性
@property (readonly, copy) NSString *domain;
@property (readonly, copy) NSString *path;
@property (nullable, readonly, copy) NSArray<NSNumber *> *portList;
2.4 得到Cookie元數(shù)據(jù)
@property (readonly, copy) NSString *name;
@property (readonly) NSUInteger version;
@property (readonly, copy) NSString *value;
2.5 確定Cookie生命周期
//過期時(shí)間
@property (nullable, readonly, copy) NSDate *expiresDate;
//一個(gè)布爾值,指示是否應(yīng)該在會(huì)話結(jié)束時(shí)丟棄cookie(無論過期日期如何)顾画。
@property (readonly, getter=isSessionOnly) BOOL sessionOnly;
2.6 Cookie安全
//一個(gè)布爾值取劫,指示是否該cookie應(yīng)該只發(fā)送到HTTP服務(wù)器。
@property (readonly, getter=isHTTPOnly) BOOL HTTPOnly;
//一個(gè)布爾值研侣,指示是否只能通過安全通道發(fā)送cookie谱邪。
@property (readonly, getter=isSecure) BOOL secure;
//一個(gè)布爾值,指示是否將cookie限制為發(fā)送回創(chuàng)建它的同一站點(diǎn)的請(qǐng)求庶诡。
@property (nullable, readonly, copy) NSHTTPCookieStringPolicy sameSitePolicy
2.7 訪問Cookie屬性
//Cookie屬性
@property (nullable, readonly, copy) NSDictionary<NSHTTPCookiePropertyKey, id> *properties;
//在cookie屬性字典中定義支持鍵的常量惦银。可直接查找文檔
NSHTTPCookiePropertyKey
2.8 獲取用戶可讀的Cookie元數(shù)據(jù)
//返回接收方的comment
@property (nullable, readonly, copy) NSString *comment;
//返回接收方的comment URL
@property (nullable, readonly, copy) NSURL *commentURL;
3. 六大特性
3.1 Cookie的生命周期
會(huì)話期Cookie: 僅作用在會(huì)話期末誓,瀏覽器關(guān)閉 后就會(huì)被自動(dòng)刪除扯俱,會(huì)話期Cookie不需要指定Expires或Max-Age部分瀏覽器提供了恢復(fù)會(huì)話功能,即使關(guān)閉瀏覽器喇澡,會(huì)話期Cookie也會(huì)被保留下來
持久性Cookie: 生命周期取決于Expires或Max-Age指定的時(shí)間(設(shè)定的時(shí)間只與客戶端相關(guān)蘸吓,而不是服務(wù)器端)
3.2 限制訪問 Cookie
有兩種方法可以確保Cookie被安全的發(fā)送,并且不會(huì)被以外的參與者或腳本訪問撩幽,Secure屬性和HttpOnly屬性
Secure屬性:
只應(yīng)通過被 HTTPS 協(xié)議加密過的請(qǐng)求發(fā)送給服務(wù)端库继,因此可以預(yù)防 man-in-the-middle 攻擊者的攻擊。但即便設(shè)置了 Secure 標(biāo)記窜醉,敏感信息也不應(yīng)該通過 Cookie 傳輸宪萄。因?yàn)?Cookie 有其固有的不安全性,Secure 標(biāo)記也無法提供確實(shí)的安全保障榨惰。
HttpOnly屬性:
JavaScript Document.cookie API 無法訪問帶有 HttpOnly 屬性的cookie拜英,此類 Cookie 僅作用于服務(wù)器
例如,持久化服務(wù)器端會(huì)話的 Cookie 不需要對(duì) JavaScript 可用琅催,而應(yīng)具有 HttpOnly 屬性居凶。
此預(yù)防措施有助于緩解跨站點(diǎn)腳本(XSS) (en-US)攻擊。
3.3 Cookie 的作用域
Domain 和 Path 標(biāo)識(shí)定義了Cookie的作用域:即允許 哪些請(qǐng)求攜帶Cookie 藤抡。
Domain 屬性:
Domain 指定了哪些主機(jī)可以接受 Cookie侠碧。如果不指定,默認(rèn)為 origin缠黍,不包含子域名弄兜。如果指定了Domain,則一般包含子域名。
Path屬性:
Path 標(biāo)識(shí)指定了主機(jī)下的哪些路徑可以接受 Cookie
SameSite attribute:
SameSite Cookie 允許服務(wù)器要求某個(gè) cookie 在跨站請(qǐng)求時(shí)不會(huì)被發(fā)送替饿,從而可以阻止跨站請(qǐng)求偽造攻擊(CSRF)
- None: 瀏覽器會(huì)在同站請(qǐng)求语泽、跨站請(qǐng)求下繼續(xù)發(fā)送 cookies,不區(qū)分大小寫视卢。
- Strict: 瀏覽器將只在訪問相同站點(diǎn)時(shí)發(fā)送 cookie踱卵。(在原有 Cookies 的限制條件上的加強(qiáng),如上文 “Cookie 的作用域” 所述)
- Lax: 與 Strict 類似据过,但用戶從外部站點(diǎn)導(dǎo)航至URL時(shí)(例如通過鏈接)除外惋砂。在新版本瀏覽器中,為默認(rèn)選項(xiàng)蝶俱,Same-site cookies 將會(huì)為一些跨站子請(qǐng)求保留班利,如圖片加載或者 frames 的調(diào)用饥漫,但只有當(dāng)用戶從外部站點(diǎn)導(dǎo)航到URL時(shí)才會(huì)發(fā)送榨呆。如 link 鏈接
Cookie prefixes:
對(duì)于子域訪問的特性,會(huì)出現(xiàn)這種情況:子域上的易受攻擊的應(yīng)用程序可以使用 Domain 屬性設(shè)置 cookie庸队,從而可以訪問所有其他子域上的該 cookie积蜻。因此cookie 的機(jī)制使得服務(wù)器無法確認(rèn) cookie 是在安全來源上設(shè)置的,甚至無法確定 cookie 最初是在哪里設(shè)置的彻消。
3.4 安全
Cookie中的信息是可以被訪問和修改的竿拆,因此具有不安全性,需要設(shè)置身份驗(yàn)證/機(jī)密機(jī)制宾尚,并且如果沒有設(shè)置安全環(huán)境時(shí)丙笋,不能通過Cookie存儲(chǔ)、傳輸敏感信息煌贴。
- 使用 HttpOnly 屬性可防止通過 JavaScript 訪問 cookie 值御板。
- 用于敏感信息(例如指示身份驗(yàn)證)的 Cookie 的生存期應(yīng)較短,并且 SameSite 屬性設(shè)置為Strict 或 Lax牛郑。
3.5 會(huì)話劫持和XSS
在 Web 應(yīng)用中怠肋,Cookie 常用來標(biāo)記用戶或授權(quán)會(huì)話。因此淹朋,如果 Web 應(yīng)用的 Cookie 被竊取笙各,可能導(dǎo)致授權(quán)用戶的會(huì)話受到攻擊础芍。
常用的竊取 Cookie 的方法有利用社會(huì)工程學(xué)攻擊和利用應(yīng)用程序漏洞進(jìn)行 XSS (en-US) 攻擊仑性。
HttpOnly 類型的 Cookie 用于阻止了JavaScript 對(duì)其的訪問性而能在一定程度上緩解此類攻擊。
3.6 跨站請(qǐng)求偽造(CSRF)
在本站點(diǎn)發(fā)送其他站點(diǎn)的請(qǐng)求嫩实,以達(dá)到惡意獲取請(qǐng)求信息的目的甲献,比如在不安全聊天室或論壇上的一張圖片颂翼,它實(shí)際上是一個(gè)給你銀行服務(wù)器發(fā)送提現(xiàn)的請(qǐng)求:當(dāng)你打開含有了這張圖片的 HTML 頁(yè)面時(shí),如果你之前已經(jīng)登錄了你的銀行帳號(hào)并且 Cookie 仍然有效球及。
阻止方法:
- 對(duì)用戶輸入進(jìn)行過濾來阻止
- 任何敏感操作都需要確認(rèn)吃引;
- 用于敏感信息的 Cookie 只能擁有較短的生命周期