互聯(lián)網(wǎng)隱私一直是一個敏感話題。很多爆炸新聞或者香艷的丑聞,似乎就像病毒一樣每隔一段時間就爆發(fā)。這不僅是網(wǎng)民茶余飯后的談資調(diào)侃,也讓部分安全公司開始吵作。用戶在安全,隱私,cookie之類宣傳攻勢,不知所以。有的人認(rèn)為cookie是泄露隱私的元兇。對于開發(fā)者,cookie的是web開發(fā)里程上的一大發(fā)明,cookie是小甜點(diǎn),絕不是惡魔。但是,如果使用不當(dāng),小甜點(diǎn)發(fā)霉了一樣會有毒。
站在用戶的角度思考問題,與客戶深入溝通,找到施甸網(wǎng)站設(shè)計(jì)與施甸網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站制作、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名與空間、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋施甸地區(qū)。
Cookie的誕生挺有意思。試想一下,當(dāng)我們?nèi)ャy行辦業(yè)務(wù)的時候,銀行職員會提供一個卡號,待會較叫號的時候,拿著卡號給柜臺業(yè)務(wù)員。這樣簡單的一種”認(rèn)證“,就是cookie的一種應(yīng)用。
web開發(fā)免不了要和cookie打交道。go的http庫也提供了cookie的相關(guān)操作。
Name字段為cookie的名字,Value是其值,剩下的Path和Domain則是cookie的存儲的范圍。Expires是cookie的過期時間,如果不設(shè)置,那么這是一個session型的cookie,即瀏覽器會話有用,一旦關(guān)閉瀏覽器,cookie隨即會被刪除。
cookie是header一項(xiàng)內(nèi)容,因此可以使用reponse的Header方法設(shè)置cookie。
這里也可以測試驗(yàn)證 Set和Add兩個方法的差別。當(dāng)然,和文件上傳類似,go也提供了常用的工具函數(shù)。
http的SetCookie方法也可以設(shè)置cookie,就不需要關(guān)系Set和Add的先后順序了,當(dāng)然第二個參數(shù)是一個Cookie的指針對象。設(shè)置了cookie,接下來就是需要讀cookie。
讀取cookie的方式也有很多,cookie封裝在header中,當(dāng)然可以通過header方法處理。
不使用Header方法,也可以使用Request的方法:
訪問的時候可以發(fā)現(xiàn),r.Cookie返回了對于key的鍵值對,而r.Cookies則返回了所有cookie的key的鍵值對值。
cookie的作用很多,通常記錄客戶端的一些信息,用來做用戶的登錄驗(yàn)證?,F(xiàn)在我們需要使用cookie來做一個小特性---消息。通常web請求發(fā)出后,response返回?cái)?shù)據(jù),也可以設(shè)置一些消息用來指引用戶。
setMessageHandler 函數(shù)很簡單,就是創(chuàng)建一個cookie實(shí)例,然后把消息寫入到cookie,然后再返回給客戶端。
getMessageHandler首先會讀取key為flash的cookie,如果沒讀到內(nèi)容,則表示消息不存在,否則就創(chuàng)建另外一個cookie,設(shè)置其過期時間這里等于清除cookie。然后把讀取出來的message返回給客戶端。完成消息通信。
我們討論了go中cookie的基本應(yīng)用。現(xiàn)在的web開發(fā)中,人們越來越重視網(wǎng)絡(luò)安全,因此cookie的安全也成為用戶關(guān)心的內(nèi)容。go原生的cookie封裝比較簡單。go的社區(qū)卻開發(fā)了很多輪子,實(shí)現(xiàn)了secure cookie,例如gorilla/securecookie庫。實(shí)際開發(fā)中,可能會借助一些三方的庫或包來完成功能。
cookie用來做認(rèn)證需要跟用戶有交互,承載交互的當(dāng)然是用戶界面。既然是關(guān)于用戶界面,學(xué)習(xí)go的模板技術(shù)就是順其自然之事。雖然現(xiàn)在前后端分離技術(shù),傳統(tǒng)的模板技術(shù)已經(jīng)逐步被前端渲染取代了,但是對于一些同構(gòu)項(xiàng)目,還是依賴部分服務(wù)端模板渲染。下一個話題再討論go的模板。
相關(guān)閱讀:
cookie wiki
全面解讀HTTP Cookie
Cookie由后端管理。
問題:第一次set cookie可以生效,第二次覆蓋或者清除cookie卻不生效。查看瀏覽器的cookie信息,仍然是第一次的值。
cookie := http.Cookie{
? ? ? ? ? ? Name:? ? name,
? ? ? ? ? ? Value:? ? value,
? ? ? ? ? ? HttpOnly: true,
? ? ? ? ? ? Secure:? false,
? ? ? ? ? ? Path:? ? "/",
? ? }
? ? http.SetCookie(resp, cookie)
原因:在第二次設(shè)置cookie,即清除cookie時,沒有設(shè)置Path
cookie := http.Cookie{
? ? ? ? ? ? Name:? name,
? ? ? ? ? ? MaxAge: -1,
? ? ? ? ? ? Expires: time.Unix(1, 0),
? ? }
? ? http.SetCookie(resp, cookie)
解決方案:
在清除Cookie時,添加Path,并且與第一次設(shè)置時的Path值一致。
用GO語言(golang)寫了一個簡單的Web服務(wù),但是始終無法獲取Cookie的值
現(xiàn)象如下:
使用Chrome的開發(fā)者工具觀察Cookie可以看到設(shè)置的Cookie的值
使用r.Cookie(CookieName)無法取得Cookie內(nèi)容,錯誤信息:http: named cookie not present
在服務(wù)器端打印Requset結(jié)構(gòu),結(jié)果中沒有設(shè)置的Cookie值
最后Google了一下,在golang-nuts的論壇里找到了解決方法。
根本原因在于GO語言(golang)不能獲取值中帶有空格的Cookie
而且會將Cookie中的一些特殊字符替換為空格
//src/pkg/net/http.go
func (c *Cookie) String() string {
...
fmt.Fprintf(b, "%s=%s", sanitizeName(c.Name), sanitizeValue(c.Value))
...
}
...
var cookieValueSanitizer = strings.NewReplacer("\n", " ", "\r", " ", ";", " ")
...
func sanitizeValue(v string) string {
return cookieValueSanitizer.Replace(v)
}
俺就是使用了分號。。。
另外討論中提到的不要使用指針傳遞http.ResponseWriter的問題,
我試了一下,使用指針傳遞http.ResponseWriter不會對Cookie的設(shè)置和取得產(chǎn)生影響
不過很多函數(shù)需要的都是http.ResponseWriter的對象,如果傳指針,很多地方要寫*http.ResponseWriter著實(shí)也挺麻煩