跨越域的Cookie (轉)

worldblog發表於2007-12-29
跨越域的Cookie (轉)[@more@]
 所有的網站開發者都會非常喜歡cookie的強大特性和易用性,它在跟蹤資訊,建設人性化、個性化的網站方面,有著強大的作用,而且,又避免了使用的昂貴開銷。但是,cookie卻不能跨越域傳遞,只有那些建立它的域才能訪問;這裡,我們討論如何利用突破這個限制。
 Cookie簡介
 首先,我們對Cookie做一個簡單的介紹,說明如何利用ASP來維護cookie。
 Cookie是在客戶端中的一個小,這就意味著每當一個使用者訪問你的站點,你就可以秘密地在它的上放置一個包含有關資訊的檔案。這個檔案幾乎可以包含任何你打算設定的資訊,包括使用者資訊、站點狀態等等。這樣的話,就有一個潛在的危險:這些資訊有可能被讀取。為了防止這個問題的發生,一個有效的辦法就是cookie只能被建立它的域所存取。這就是說:比如ytu.edu.cn只能訪問ytu.edu.cn建立的cookie。通常來講,這沒有什麼問題;但是,如果需要兩個不同域上的兩個不同站點共享儲存在cookie中的使用者資訊,該如何處理呢?當然可以選擇複製使用者信,但是,如果你需要使用者只能在一個站點上註冊,並且自東成為另外一個站點的註冊使用者呢?或者,兩個站點共享一個使用者資料庫,而又需要使用者自動登入呢?這時候,跨越域共享cookie是最好的解決方案。
 這裡,先看一些ASP處理cookie的程式碼,以便以後便於引用參考。
 '建立Cookie
 Response.("MyCookie").Expires=Date+365
 Response.Cookies("MyCookle").ain="mydomaln.com"
 Response.Cookies("MyCookle")("Username")=strUsername
 Response.Cookies("MyCookle")("Pass")=strPassword
 讀寫cookie非常簡單,上面的程式碼建立一個cookie並給cookie設定屬性:域、過期時間,以及其他一些儲存在cookie中的值。這裡,strUsename,strPassword是在前面某個地方設定的變數。然後,透過下面的語句在cookie中讀取。
 '讀取Cookie
 datExpDate=Request.Cookies("MyCookie")
 strDomaln=Request.Cookies("MyCookle").Domain
 strUsername=Request.Cookies("MyCookle")("Username")
 strPassword=Request.Cookies("MyCookie")("Password")
 更詳細的資訊,可以參考ASP的資料。

 實現
 簡單地共享cookie的訣竅是重定向,一般過程為:
 1.一個使用者點選siteA.com。
 2.如果使用者沒有siteA.com的cookie,就把使用者重定向到siteB.com。
 3.如果使用者有siteB.com的cookie,把使用者連同一個特殊的標誌(將在下面解釋)重定向回siteA.com,否則,只把使用者重定向到siteA.com。
 4.在siteA.com建立cookie。
 看起來很簡單,仔細分析一下:siteA.com和siteB.com共享相同的使用者設定,所以,如果使用者有siteB.com的cookie(已經註冊),siteA.com能夠同樣讀取cookie、提供cookie所允許的特性。這樣,訪問siteA.com的使用者就如同訪問了siteB.com。
 這個檢查的環節應該在siteA.com中的檔案所包含一個cookies.inc中實現。讓我們看一下這段程式碼:
 l—1
 'SiteA.com"檢查cookie
 If Request.Querystring("Checked")<>"True" then
 If not Request.Cookies("SiteA_Cookie").Haskeys then
 '重走向到siteB.com
 Response.Redlrect("")
 End if
 End if

 如果使用者有一個siteA.com的cookie,則不需要做任何事情了;第一個if語句用來消除無限的迴圈。讓我們看一下siteB.com上的cookie.asp檔案來獲得進一步的理解。
 1—2
 'SiteB.com
 '檢查cookie
 If not Request.Cookies("SlteB_Cookle").Haskeys then
 '重定向到 siteA.com
 Response.Redirect(""&"?checked=True")
 Else
 '獲取username
 strUsername=Request.Cookies("SiteB_Cookie")("Username")
 '將使用者連同一個特殊的標誌返回到siteA.com
 Response.Redlrect(""&"?checked=True"&"ntrfer="&strUsername)
 End if
 如果使用者在siteB.com上仍沒有cookie,於是,將他送回到siteA.com,並且透過在查詢語句中提供一個叫做"checkd"的引數讓應用知道你已經檢查過cookie了。否則,將使用者送回到siteB.com,並退出迴圈。
 然而,如果使用者擁有siteB.com的cookie,我們需要將使用者送回siteA.com並告訴siteA.com。為此,我們在資料庫中附加一個唯一的標誌,username。所以,我們擴充套件siteA.com中的程式碼。
 l—3
 'SiteA.com
...
...
 '檢查標誌
 If Request.Querystring("identifier")<>"" then
 strUsername=Request.Querystring("identifier")
 '記錄到資料庫
 Response.Cookies("siteA_Cookie").Expires=Date+365
 Response.Cookies("SiteA_Cookie").Domain="siteA.com"
 Response.Cookies("siteA_Cookie")("Username")=strUsername
 End if
 最後,我們回到siteA.com。檔案的第一部分(l-l)檢查是否完成了cookie的檢查,由於可以明顯地知道已經完成(由語句中的"checked"參數列明),進行到l—3所示的程式的第二部分。如果存在特殊的標誌,我們就可以在siteA.com建立cookie。使用這個特殊的標誌(在這裡是username),我們可以在任何需要的時候查詢資料庫。然後,設定cookie,顯示頁面的其他部分。如果沒有指定的標誌,也沒必要擔心,只要簡單地顯示頁面的餘下部分。
 這樣,毫不費力地,siteA.com擁有了和siteB.com一樣的cookie。我們可以傳輸更多的資訊而不只是一個標誌,並且,將流量控制在最小範圍內。
 要注意一點,即使使用者擁有siteA.com上的cookie,仍需要檢查siteB.com。通常來講,這不是必須的,也會節約時間。但是,一旦使用者在siteB.com更改個人資訊?這樣做,會保持所有資訊的同步。

 Cookie環
 要完成這些,我們需要兩個檔案:一個在原始站點(siteA.com),完成檢查;一個在參考伺服器(siteB.com),驗證使用者。如果有一臺參考伺服器包含有需要的所有使用者資訊或cookie,就可以增加隨意多的原始伺服器,所需要做的就是在所有要共享cookie的伺服器上增加cookie.inc檔案。
 也可以以相反的次序,例如,如果siteB.com是原始伺服器,而siteA.com包含使用者資訊。訪問過siteA.com卻從未訪問過siteB.com的使用者也可以登入到siteA.com,並且擁有所有的曾經的設定。注意,如果擁有多個參考伺服器,這樣將會很使人迷惑,並且消耗過多的資源,因為必須將使用者重定向到每一臺參考伺服器。
 理論上講,可以擁有一個所有站點都共享相同的使用者的網路。最可行的方案就是建立共享cookie環。將參考伺服器列表儲存在一個地方(伺服器),以便每個參考伺服器可以查詢並決定重定向使用者的下一個站點。記住一定要透過查詢字串的意思跟蹤使用者是在哪個原始伺服器開始。這樣資訊的傳輸非常迅速,這個環節變得越來越可行。
 這裡還存在一些問題,首先是反應時間。對使用者而言,他們最好不知道過程是怎樣的。他所需的時間依賴於siteA.com、siteB.com之間的連線,有可能會比較長,在實現cookie環時可能會更長。
 再一個主要問題,就是每一個實現者大都會面對無限的重定向。這有很多原因,例如:使用者的測覽器不支援cookie。這就需要再設計程式碼來監測使用者的。
 最好,還需要注意問題。如果有些駭客發現了其中的訣竅,他可能會得到cookie中的資訊。最簡單的防範辦法就是保護參考伺服器,只允許原始伺服器訪問Cookie.asp檔案。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-996077/,如需轉載,請註明出處,否則將追究法律責任。

相關文章