修改网址。响应作为函数参数传递时的编写器

我有一个处理应用程序身份验证的身份验证中间件,有几个检查案例,每个检查都有相同的逻辑,以防出现错误:


res, err := doSomeCheck()

if err != nil {

    log.Println("Authentication failed: %v", err)

    json.NewEncoder(w).Encode(struct {Error string}{Error: "something is broke!"})

    w.Header().Set("Content-Type", "application/json")

    w.WriteHeader(http.StatusForbidden)

    return

}

我想用一些这样的函数编写这个逻辑(每种情况之间的唯一区别是错误和客户端消息):


func authError(w http.ResponseWriter, err error, clientMsg string) {

    log.Println("Authentication failed: %v", err)

    json.NewEncoder(w).Encode(struct {

        Error string

    }{Error: clientMsg})

    w.Header().Set("Content-Type", "application/json")

    w.WriteHeader(http.StatusForbidden)

    return

}

但不是指针(我没有将其作为中间件处理程序的指针获取),因此我无法从函数中更改它,也不会更改实际响应。我怎样才能优雅地完成这项工作?wauthError()


www说
浏览 133回答 1
1回答

慕斯王

w不是指针,但它是接口类型,它将指针包装在引擎盖下。因此,您可以按原样传递它,当您调用其方法时,它将反映在调用方中。只是不要忘记,如果之前有任何东西写到响应,你不能(再次)写标题。同样,如果您向输出写入某些内容,则调用方无法将其取回。如果生成响应,则在这种情况下,调用方应返回。authError()authError()另请注意,必须首先设置标头,然后调用 ,然后才能写入响应正文。ResponseWriter.WriteHeader()如果调用 ,则将写入响应状态(如果尚未写入)(假设 )。ResponseWriter.Write()HTTP 200 OK引用自回复作家.write():// If WriteHeader has not yet been called, Write calls// WriteHeader(http.StatusOK) before writing the data. If the Header// does not contain a Content-Type line, Write adds a Content-Type set// to the result of passing the initial 512 bytes of written data to// DetectContentType. Additionally, if the total size of all written// data is under a few KB and there are no Flush calls, the// Content-Length header is added automatically.Write([]byte) (int, error)所以你应该是这样的:authError()func authError(w http.ResponseWriter, err error, clientMsg string) {    log.Println("Authentication failed: %v", err)    w.Header().Set("Content-Type", "application/json")    w.WriteHeader(http.StatusForbidden)    err = json.NewEncoder(w).Encode(struct {        Error string    }{Error: clientMsg})    if err != nil {        log.Println("Failed to write response: %v", err)    }    return}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go