1. 程式人生 > >asp跨域共用cookie和session的問題

asp跨域共用cookie和session的問題

       這幾天因為網站涉及到二極域名共用session的問題,頭痛。在網上找了好久的料,終於在csdn裡面找到2004年前輩們討論的解決方案,個人感覺很 受用。

樓主 yufeiyxl(與 飛)

我要向各位請教的是Cookie的跨域訪問問題。   
        問題是這樣的:   
        我 有一個網站,它有多個頻道構成(比如說三個),他們共享一個數據庫,這三個頻道都提供登入功能,只要在其中的一個頻道登入了,就直接可以進入其他頻道,無 需再登入。   
        我看了幾篇文章,還是沒搞懂,希望各位高人,給與我幫助,解決之後立即給分。我先謝謝各位了。  

5 樓 net_lover(【孟子E章】)

跨越域的Cookie  
   
  日期:2003-1-8   10:12:34  
  作者:趙金東    
     
  所有的網站開發者都會非常喜歡cookie的強大特性和易用性,它在跟蹤使用者資訊,建設人性化、個性化的網站方面,有著強大的作用,而且,又避免了使用數 據庫的昂貴開銷。但是,cookie卻不能跨越域傳遞,只有那些建立它的域才能訪問;這裡,我們討論如何利用ASP突破這個限制。  
  Cookie簡介  
  首先,我們對Cookie做一個簡單的介紹,說明如何利用ASP來維護cookie。  
  Cookie是儲存在客戶端計算機中的一個小檔案,這就意味著每當一個使用者訪問你的站點,你就可以祕密地在它的硬碟上放置一個包含有關資訊的檔案。這個文 件幾乎可以包含任何你打算設定的資訊,包括使用者資訊、站點狀態等等。這樣的話,就有一個潛在的危險:這些資訊有可能被黑客讀取。為了防止這個問題的發生, 一個有效的辦法就是cookie只能被建立它的域所存取。這就是說:比如ytu.edu.cn只能訪問ytu.edu.cn建立的cookie。通常來 講,這沒有什麼問題;但是,如果需要兩個不同域上的兩個不同站點共享儲存在cookie中的使用者資訊,該如何處理呢?當然可以選擇複製使用者信,但是,如果 你需要使用者只能在一個站點上註冊,並且自東成為另外一個站點的註冊使用者呢?或者,兩個站點共享一個使用者資料庫,而又需要使用者自動登入呢?這時候,跨越域共 享cookie是最好的解決方案。  
  這裡,先看一些ASP處理cookie的程式碼,以便以後便於引用參考。  
  '建立Cookie  
  Response.Cookies("MyCookie").Expires=Date+365  
  Response.Cookies("MyCookle").Domain="mydomaln.com"  
  Response.Cookies("MyCookle")("Username")=strUsername  
  Response.Cookies("MyCookle")("Password")=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("http://www.siteB.com/cookie.asp")  
  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("http://www.siteA.com/index.asp"&"?checked=True")  
  Else  
  '獲取username  
  strUsername=Request.Cookies("SiteB_Cookie")("Username")  
  '將使用者連同一個特殊的標誌返回到siteA.com  
  Response.Redlrect("http://www.siteA.com/index.asp"&"?checked=True"&"identrfer="&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檔案。  

14 樓 bluemoon0001(小 天--追夢浪子)

另一個貼的:  
   
  借用http://community.csdn.net/Expert/topic/3487/3487066.xml?temp=.723675  
  的思路,轉為Session  
  比如:A站使用者在A站登陸,驗證能過後,在A站建立  
    session("username")=username  
    session("password")=password  
  Response.Redirect("http://www.siteB.com/login.asp"&"?checked=yes&username="&username&"&password="&password)  
   
  B站login.asp:  
   
  if   request("checked")=""   then   '本站提交的驗證  
        ....  
  elseif   request("checked")="yes"   then   'A站帶過來的驗證(在A站已通過,在這裡記錄一下session)  
      session("username")=request("username")  
    session("password")=request("password")  
   
  else                   ''A站帶過來的驗證(在A站沒通過,需要在B站驗證)  
    在B站驗證  
  end   if  
   
  驗證過後,再導回A站多帶一個標記引數,說明,這是是A站導過來的,在B站經過驗證的,你自己再想想辦法,做一下改動吧,這些是思路。 

15 樓 bluemoon0001(小天 --追夢浪子)

對上面做一個修改,你再看一下:  
   
    session("username")=username  
    session("password")=password  
  Response.Redirect("http://www.siteB.com/login.asp"&"?checked=yes&username="&username&"&password="&password&"&comeform="A)  
   
  B站login.asp:  
   
  if   request("checked")=""   then   '本站提交的驗證  
          session("username")=username  
          session("password")=password  
          Response.Redirect("http://www.siteA.com/login.asp"&"?checked=yes&username="&username&"&password="&password&"&comeform=B")  
        elseif   request("checked")="yes"   then   'A站帶過來的驗證(在A站已通過,在這裡記錄一下session)  
      session("username")=request("username")  
    session("password")=request("password")  
    if   request("comeform")="A"   then  
        Response.Redirect("http://www.siteA.com/login.asp"&"?checked=yes&username="&username&"&password="&password&"&comeform=A")  
    end   if  
  elseif   request("comeform")="A"   then                   ''A站帶過來的驗證(在A站沒通過,需要在B站驗證)  
       
    在B站驗證  
    ....  
    session("username")=username  
          session("password")=password  
          Response.Redirect("http://www.siteA.com/login.asp"&"?checked=yes&username="&username&"&password="&password&"&comeform=A")   '   通過checked設為yes沒有設為no,在這裡我假設的是通過的,沒通過的,你自己寫一下。  
  else  
        response.write   "使用者名稱或密碼錯誤"  
  end   if