我希望從我的處理程序中提取一些重復的邏輯并將其放入一些每個處理程序的中間件中:特別是 CSRF 檢查、檢查現有會話值(即身份驗證或預覽頁面)等。我已經閱讀了一些關于此的文章,但許多示例都集中在每個服務器的中間件(包裝http.Handler)上:我有一組較小的處理程序需要中間件。我的大多數其他頁面都沒有,因此如果我可以避免檢查會話/等。對于那些要求更好。到目前為止,我的中間件通??雌饋硐襁@樣:func checkCSRF(h http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // get the session, check/validate/create the token based on HTTP method, etc. // return HTTP 403 on a failed check // else invoke the wrapped handler h(w, r) }}然而,在許多情況下,我想將一個變量傳遞給包裝的處理程序:生成的 CSRF 令牌傳遞給模板,或包含表單數據的結構——一個中間件檢查會話之前是否存在一些保存的表單數據用戶點擊一個/preview/URL,否則它會將它們重定向(因為它們沒有任何東西可以預覽?。?。我想將該結構傳遞給包裝的處理程序,以避免重復我剛剛在中間件中編寫的 session.Get/類型斷言/錯誤檢查邏輯。我可以這樣寫:type CSRFHandlerFunc func(w http.ResponseWriter, r *http.Request, t string)...然后像這樣編寫中間件:func csrfCheck(h CSRFHandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // get the session, check/validate/create the/a token based on HTTP method, etc. // return HTTP 403 on a failed check // else invoke the wrapped handler and pass the token h(w, r, token) }......但這提出了幾個問題:這是實現每個處理程序中間件并傳遞每個請求變量的明智方法嗎?在對此進行測試之前(無法訪問我的開發機器!),如果我需要用多個中間件包裝處理程序,我認為我可以r.HandleFunc("/path/preview/", checkCSRF(checkExisting(previewHandler)))嗎?我在這里看到的問題是中間件現在是緊密耦合的:包裝的中間件現在需要接收然后傳遞來自外部中間件的變量。這使得擴展 http.HandlerFunc 更棘手/更復雜。將大猩猩/背景更適合這里,讓我避免寫2-3自定義的處理器類型(或通用處理器類型) -如果有的話,我會如何利用它?或者我可以實現我自己的“上下文”映射(并遇到并發訪問問題?)。在可能的情況下,我試圖避免陷入“不要陷入編寫庫”的陷阱,但是中間件是我可能會在項目生命后期添加/構建的東西,我想“第一次做對”。對此的一些指導將不勝感激。到目前為止,Go在編寫 Web 應用程序方面非常出色,但在其生命周期的現階段還沒有大量示例,因此我有點依賴 SO。
1 回答

楊魅力
TA貢獻1811條經驗 獲得超6個贊
如果我正確理解了您的問題,那么您正在尋找一種方便的方法來將附加參數傳遞給您的中間件,對嗎?
現在,定義這些參數是什么很重要。它們可能是您的中間件的一些配置值——可以在構造 Handler 類型時設置這些值)。而不是NewMyMiddleware(MyHandler)
,你做NewMyMiddleware(MyHandler, "parameter")
,這里沒問題。
但是在您的情況下,您似乎想傳遞每個請求的參數,例如 CSRF 令牌。將這些傳遞給處理函數會修改其簽名,并且會偏離標準Handler[Func]
接口。在這種情況下,您對中間件的耦合更加緊密是正確的。
你自己提到了解決方案——在我看來,上下文地圖是一個可行的工具。這不是說很難一個寫自己-你基本上需要map[*http.Request]interface{}
和RWMutex
安全的并發訪問。盡管如此,簡單地使用gorilla/context
應該就足夠了——它似乎是一個(相對)成熟的、編寫良好的包,帶有一個很好的 API。
無恥的插件:如果你正在處理 CSRF 檢查,為什么不試試我的nosurf包?
- 1 回答
- 0 關注
- 226 瀏覽
添加回答
舉報
0/150
提交
取消