为了账号安全,请及时绑定邮箱和手机立即绑定

go-swagger Oauth2 身份验证示例

go-swagger Oauth2 身份验证示例

Go
慕娘9325324 2022-07-11 16:06:36
https://github.com/go-swagger/go-swagger/blob/master/examples/oauth2/restapi/configure_oauth_sample.go谁能解释这段代码的用途?// This demonstrates how to enrich and pass custom context keys.// In this case, we cache the current responseWriter in context.type customContextKey int8const (    _ customContextKey = iota    ctxResponseWriter)// The middleware configuration is for the handler executors. These do not apply to the swagger.json document.// The middleware executes after routing but before authentication, binding and validationfunc setupMiddlewares(handler http.Handler) http.Handler {    ourFunc := func(w http.ResponseWriter, r *http.Request) {        rctx := context.WithValue(r.Context(), ctxResponseWriter, w)        handler.ServeHTTP(w, r.WithContext(rctx))    }    return http.HandlerFunc(ourFunc)}丰富和传递自定义上下文键是什么?
查看完整描述

1 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

简而言之:这是将自定义中间件应用于您的 go-swagger 应用程序服务的所有路由。该中间件将ResponseWriter作为自定义值添加到请求上下文中。可以肯定的是,这与 OAuth 无关。


一步一步来:


这context是一种特殊类型,可以跨代码层携带请求范围的值、截止日期和取消信号。


type customContextKey int8

在这里,我们定义了一个未导出的上下文键类型。我们这样做的原因是,当我们将值添加到上下文时,我们希望该值不会与其他可能与上下文交互的包设置的值发生冲突。例如,如果我们只使用字符串“customContextKey”而其他一些包碰巧使用相同的字符串,就会发生这种情况。更多信息在这里。


const (

    _ customContextKey = iota

    ctxResponseWriter

)

这里我们创建了一个customContextKey名为ctxResponseWriter1 的值。请注意,我们忽略 ( _) 的第一个值为iota0,而是使用下一个值 1。这是用于存储的类型安全键上下文中的实际ResponseWriter值。


中间件是接受 ahttp.Handler并返回 a的函数http.Handler,它们可以组合在一起,并且是一种以通用方式向应用程序处理程序添加额外功能的模式。要更深入地了解,请查看制作和使用 HTTP 中间件。


func setupMiddlewares(handler http.Handler) http.Handler {

    ourFunc := func(w http.ResponseWriter, r *http.Request) {

        rctx := context.WithValue(r.Context(), ctxResponseWriter, w)

        handler.ServeHTTP(w, r.WithContext(rctx))

    }

    return http.HandlerFunc(ourFunc)

}

这里的函数以如下方式包装给定的处理程序:

  • 上下文从请求中提取——r.Context()

  • 用我们的新密钥和价值“丰富” w ResponseWriter——context.WithValue(..., ctxResponseWriter, w)

  • 请求的上下文被更新的上下文替换——r.WithContext(rctx)

  • 包装的处理程序与这个更新的请求一起运行——handler.ServeHTTP(w, ...)

在一些 http.Handler 中,您可能会像这样提取值:

func someHandler(w http.ResponseWriter, r *http.Request) {

    value, ok := r.Context().Value(ctxResponseWriter).(http.ResponseWriter)

    if ok {

        // we have the value!

    }

}

这一定只是一个使用示例。像这样传递 ResponseWriter 是非常愚蠢的,因为它已经作为参数传递给任何 http.Handler ,正如您在上面看到的那样,并且从应用程序的更深层依赖它是糟糕的设计。例如,更好的用途可能是传递请求范围的记录器对象。


查看完整回答
反对 回复 2022-07-11
  • 1 回答
  • 0 关注
  • 184 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信