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

huangapple go评论97阅读模式
英文:

Go: How to use context value in a variable?

问题

我正在使用上下文将用户负载(特别是用户ID)附加到我的Go REST应用程序的中间件中。

  1. // 中间件
  2. // 将负载附加到请求上下文
  3. claimsWithPayload, _ := token.Claims.(*handlers.Claims)
  4. ctx := context.WithValue(r.Context(), "userid", claimsWithPayload.Id)
  5. req := r.WithContext(ctx)
  6. h := http.HandlerFunc(handler)
  7. h.ServeHTTP(w, req)

然后在HTTP处理程序中,我需要提取该用户ID作为string/integer,但是context().Value()返回一个interface{}

  1. // 处理程序
  2. a := r.Context().Value("userid") // 这返回一个interface{}
  3. response := []byte("您的用户ID是" + a) // 如何将其用作字符串/整数??
  4. w.Write(response)

请注意,上述代码片段中的注释已经被我翻译成了中文。

英文:

I am using context to attach user payload(userId specifically) in a middleware for my go rest application

  1. // middleware
  2. // attaching payload to the request context
  3. claimsWithPayload, _ := token.Claims.(*handlers.Claims)
  4. ctx := context.WithValue(r.Context(), "userid", claimsWithPayload.Id)
  5. req := r.WithContext(ctx)
  6. h := http.HandlerFunc(handler)
  7. h.ServeHTTP(w, req)

And later in a http handler, I need to extract that userid as string/integer
but context().Value() returns an interface{}

  1. // handler
  2. a := r.Context().Value("userid") // THIS returns an interface{}
  3. response := []byte("Your user ID is" + a) // 👈 how do I use it as a string/integer??
  4. w.Write(response)
  5. </details>
  6. # 答案1
  7. **得分**: 7
  8. 你可以使用类型断言将上下文值转换为其底层类型
  9. ```go
  10. a := r.Context().Value("userid").(string)

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

  1. type contextKey string
  2. const userIDKey contextKey = "userid"
  3. ...
  4. ctx := context.WithValue(r.Context(), userIDKey, claimsWithPayload.Id)
  5. ...
  6. a := r.Context().Value(userIDKey).(string)

由于contextKeyuserIDKey是未导出的,只有你的包才能从上下文中读取或写入该值。

英文:

You can use a type assertion to get the context value as its underlying type:

  1. a := r.Context().Value(&quot;userid&quot;).(string)

This will panic if the value stored by the middleware is not a string, or if something else sets the context key to something which is not a string. To guard against this you should never use builtin types as context keys, instead define your own type and use that:

  1. type contextKey string
  2. const userIDKey contextKey = &quot;userid&quot;
  3. ...
  4. ctx := context.WithValue(r.Context(), userIDKey, claimsWithPayload.Id)
  5. ...
  6. a := r.Context().Value(userIDKey).(string)

Because contextKey and userIDKey are unexported, only your package can read or write this value from or to the context.

huangapple
  • 本文由 发表于 2022年1月10日 19:16:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/70651544.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定