如何设置多值HTTP标头,例如Content-Security-Policy?

问题描述 投票:2回答:3

我正在尝试在http.ResponseWriter对象上设置Content-Security-Policy标头。这是一个包含多个值的标头。我的问题是http.Header的所有方法都采用单个键和单个值。例如,Set() method看起来像这样:

func (h Header) Set(key, value string)

没有方法可以为标题字段分配值。我想要一个看起来像这样的标题。

header := http.Header{
    "Content-Type": {"text/html; charset=UTF-8"},
    "Content-Security-Policy": {"default-src 'self'", "font-src themes.googleusercontent.com", "frame-src 'none'", "style-src 'self' fonts.googleapis.com"},
}

这将创建标题,但我不知道如何将它与http.ResponseWriter对象关联。此外,如果我以某种方式能够用上面的标题替换ResponseWriter的标题,我是否必须手动设置Content-Length字段?

go http-headers content-security-policy
3个回答
2
投票

我不确定我是否完全理解这个问题,但是Content-Security-Policy期望一个包含由;分隔的列表的标题。

如果你想使用切片,你总是可以使用这样的东西:

csp := []string{"default-src: 'self'", "font-src: 'fonts.googleapis.com'", "frame-src: 'none'"}
header := http.Header{
    "Content-Type": {"text/html; charset=UTF-8"},
}
header.Set("Content-Security-Policy", strings.Join(csp, "; "))

此外,如果你想用不同的值多次发送标题(我想你最初想要的话),你可以使用header.Add

添加将键,值对添加到标题。它附加到与key关联的任何现有值。

如果要在http处理程序中使用它,请使用ResponseWriter.Header()获取标头:

func Handler(rw http.ResponseWriter, req *http.Request) {
    header := rw.Header()
    csp := []string{"default-src: 'self'", "font-src: 'fonts.googleapis.com'", "frame-src: 'none'"}

    header.Set("Content-Type": "text/html; charset=UTF-8")
    header.Set("Content-Security-Policy", strings.Join(csp, "; "))
    rw.WriteHeader(200) //or write anything really
}

1
投票

这不直接(尚未)解决CSP问题,但它确实涵盖了“其他4个”安全标头

http://godoc.org/github.com/kr/secureheader


0
投票

我创建了一个中间件来设置CSP标头。

package main

import (
    "gorila-mux/ctrls"
    "log"
    "net/http"

    "github.com/gorilla/context"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/", ctrls.HomeHandler)
    r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir("public/"))))
    http.Handle("/", r)
    r.Use(setCSPHeaders)
    log.Print("Project is serving on port 7000 : http://localhost:7000")
    http.ListenAndServe(":7000", context.ClearHandler(http.DefaultServeMux))

}


func setCSPHeaders(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        //  w.Header().Set("Content-Type", "application/json; charset=utf-8")
        w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; object-src 'self';style-src 'self' img-src 'self'; media-src 'self'; frame-ancestors 'self'; frame-src 'self'; connect-src 'self'")
        next.ServeHTTP(w, r)
    })
}
© www.soinside.com 2019 - 2024. All rights reserved.