Go:如何在变量中使用上下文值?

Kar*_*mar 6 go

我正在使用上下文在我的 Go Rest 应用程序的中间件中附加用户有效负载(特别是 userId)

// middleware
    // attaching payload to the request context
        claimsWithPayload, _ := token.Claims.(*handlers.Claims)
        ctx := context.WithValue(r.Context(), "userid", claimsWithPayload.Id)
        req := r.WithContext(ctx)
        h := http.HandlerFunc(handler)
        h.ServeHTTP(w, req)
Run Code Online (Sandbox Code Playgroud)

稍后在 http 处理程序中,我需要提取该用户 ID,string/integer 因为 context().Value() 返回一个接口{}

// handler 
a := r.Context().Value("userid") // THIS returns an interface{}
response := []byte("Your user ID is" + a) //  how do I use it as a string/integer??
w.Write(response)
Run Code Online (Sandbox Code Playgroud)

Bra*_*ken 10

您可以使用类型断言来获取上下文值作为其基础类型:

a := r.Context().Value("userid").(string)
Run Code Online (Sandbox Code Playgroud)

如果中间件存储的值不是字符串,或者其他内容将上下文键设置为不是字符串,则会出现恐慌。为了防止这种情况,你不应该使用内置类型作为上下文键,而是定义你自己的类型并使用它:

type contextKey string
const userIDKey contextKey = "userid"
...
ctx := context.WithValue(r.Context(), userIDKey, claimsWithPayload.Id)
...
a := r.Context().Value(userIDKey).(string)
Run Code Online (Sandbox Code Playgroud)

因为contextKeyuserIDKey未导出,所以只有您的包可以从上下文读取或写入该值。

  • @KaranKumar 类型断言支持“comma-ok”习惯用法,这意味着,为了避免恐慌,您可以执行“a, ok := val.(string)”。如果“val”为“nil”或“string”以外的其他值,则“ok”变量将设置为“false”,而“a”将设置为“””。如果“val”是“string”,则“ok”将设置为“true”,“a”将设置为字符串值。 (2认同)