1 回答

TA貢獻1818條經驗 獲得超11個贊
WithContext
返回請求的淺表副本,即創建的請求與從中讀取上下文的authMiddleware
請求不同。logMiddleware
您可以讓根中間件(在本例中為logMiddleware
)創建帶值的上下文和淺請求副本,但不是普通字符串在上下文中存儲非零指針authMiddleware
,然后使用指針間接分配指針指向的值,然后logMiddleware
,在next
退出后,可以取消引用該指針以訪問該值。
并且為了避免不愉快的取消引用,您可以使用指向帶有字符串字段的結構的指針,而不是指向字符串的指針。
type ctxKey uint8
const userKey ctxKey = 0
type user struct{ name string }
func logMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u := new(user)
r = r.WithContext(context.WithValue(r.Context(), userKey, u))
defer func(start time.Time) {
if u.name != "" {
fmt.Printf("user %s has accessed %s, took %s\n", u.name, r.URL.Path, time.Since(start))
} else {
fmt.Printf("annonyous has accessed %s, took %s\n", r.URL.Path, time.Since(start))
}
}(time.Now())
next.ServeHTTP(w, r)
})
}
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if u, ok := r.Context().Value(userKey).(*user); ok {
u.name = "user123"
}
next.ServeHTTP(w, r)
})
}
func welcome(w http.ResponseWriter, r *http.Request) {
if u, ok := r.Context().Value(userKey).(*user); ok && u.name != "" {
fmt.Fprintf(w, "hello %s", u.name)
} else {
fmt.Fprintf(w, "hello")
}
}
https://go.dev/play/p/N7vmjQ7iLM1
- 1 回答
- 0 關注
- 102 瀏覽
添加回答
舉報