struts2令牌(token)內部原理

覺的文章很好,轉過來了。轉自:http://www.cnblogs.com/iyangyuan/archive/2013/05/05/3060488.html

 小菜最近接觸了struts2中的令牌知識,由於該知識點比較重要,因此想弄明白些,於是滿懷信心的上網查閱資料,結果讓小菜很無奈,網上的資料千篇一律,總結出來就一句話:“訪問頁面時,在頁面產生一個token id,同時在服務器的session中保存一個同樣的id,提交時判斷如果相同怎麼樣不相同怎麼樣。。。”

    可能是小菜愚笨,實在是無法從這麼精煉的描述中體會令牌的精髓。

    膚淺的那麼一說,然後上來就是一堆代碼,有時候對初學者的幫助可能不是很大,如果能夠介紹一下其中的原理,無疑會加快讀者學習速度。

    經過刻苦的研究,下面小菜來介紹一下,令牌究竟是如何做到防止界面刷新的。

    本文不涉及令牌具體用法,只講原理。

    首先需要說明的是,在struts2框架中使用令牌基本上就是兩步:

        l  在jsp頁面中使用<s:token></s:token>標籤,可以放在表單中任何位置,這個標籤的作用就是在頁面中產生一個token id,可以通過“查看源文件”的形式看到。爲什麼要放在表單中呢?因爲這個是要提交到服務器的,要不然服務器怎麼知道你的id是多少?

        l  在struts2核心配置文件中爲token攔截器添加參數,來指明需要攔截哪些方法,例如:<interceptor-ref name="token"><param name="includeMethods">save</param></interceptor-ref>,指明攔截save方法。當然也可以用excludeMethods來聲明不攔截哪些方法。

                  

令牌生成原理圖:

    從圖中可以看出,如果某個jsp頁面中有token標籤,那麼無論是請求這個界面還是內部轉發到這個界面,我們統一說成是“渲染界面”的時候,都會造成token id的產生或者更新。

    一定要搞清楚,這裏是請求的jsp頁面,此時可以產生令牌,但令牌不會起作用,因爲它攔截的不是jsp,而是通過反射機制調用的方法。

 

令牌攔截原理圖:

     從圖中可以看出,令牌可以攔截的是Action中的方法。

     如果方法需要被攔截,會判斷session中的token id和提交過來的token id是否相等。如果不相等,則直接跳轉到預先配置好的界面,session中的token id不變;如果相等,則執行請求的方法,關鍵的一點是,此時session中的token id會被清空!這個步驟非常關鍵!

 

綜上,關於令牌的使用,記住以下幾點,基本可以應對各種複雜的令牌應用場景

 

    l  注意令牌的產生時機,它是在加載(或渲染)帶有token標籤的jsp頁面時產生的,與請求或者轉發無關,與方法是否被攔截無關。

    l  由於服務器端的token id是保存在session中的,因此不同的頁面間可以共享,使用時注意,避免混亂。

    l  如果訪問的方法屬於被攔截的方法,驗證通過之後,會清空session中的token id;如果驗證不通過,session 中的token id不變,直到下一次加載(或渲染)帶有token標籤的jsp頁面。

 

    再多囉嗦一些,爲什麼驗證通過後要清空session中的token id呢?其實不難理解,從宏觀上來思考,重複提交有一個必然的特徵:它的token id是上一個。因此只要保證驗證通過後session中保存的token id變化即可,清空是最直接的辦法。要想通過驗證,只有一個途徑:重新加載(或渲染)帶有token標籤的jsp頁面,使客戶端的token id和服務器端的token id一致。

    小菜總是希望自己的文章能夠幫助更多的人,因此寫的有點囉嗦,大家見諒!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章