Golang:带标题的http.Redirect()

Pee*_*ter 4 http go

我有一个模拟授权API访问的网页.用户输入API URL和授权密钥(假设为"true"或"false").在Go方面,这个路径有一个处理函数,它读取表单并根据授权密钥生成一个令牌.
理想情况下,我想将令牌保存为标头,并根据输入的API网址将请求重定向到正确的处理程序.但是,当我使用http.Redirect()时,我的标头不会作为请求的一部分发送.

func createTokenHandler(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    path := r.FormValue("path")
    auth := r.FormValue("auth") // let's say "true" or "false"
    w.Header().Set("auth", auth)
    http.Redirect(w, r, path, http.StatusFound) // is this the correct http code?
}

// path redirects to this handler
func otherPathHandler(w http.ResponseWriter, r *http.Request) {
    // these were necessary for cross-domain requests to work with custom header, keeping them
    w.Header().Set("Access-Control-Allow-Origin", "*")
    w.Header().Set("Access-Control-Allow-Headers", "auth")
    auth = r.Header.Get("auth")
    if auth == "true" {
        w.Write([]byte("Validated, here's the API response."))
        // continue
    }
}
Run Code Online (Sandbox Code Playgroud)

可能有几个具有不同路径的API网址,但我的思维过程每次都将令牌写入同一个处理函数中的标头.我之所以这样设计,是因为API网址最终可能会重定向到不同的域名,因此我希望将其与阅读表单分开.
Google告诉我以某种方式使用Client.CheckRedirect,但我不确定如何在我的处理程序函数中实现它.如何在保留标题的同时重定向?谢谢!

edu*_*911 10

这是因为HTTP标准不通过302/301指令上的HTTP标头.这不是GoLang问题,而是HTTP 1.0(和2.0?)标准问题.

您正在思考,使用POST-REDIRECT-GET模式将常见的FORM发布到您的Web应用程序(它会阻止旧浏览器刷新"您要重新提交表单吗?"烦人的错误).

顺便说一句,是的,这是正确的状态代码.请注意,这http.StatusFound是一个302代码,表示它是临时移动.切勿将301永久移动状态用于回发重定向.

但是有一些常见的解决方法.

会议

有几种服务器端语言Sessions将值存储在后端.

  • 将值/结果存储在与后端DB上的用户会话关联的变量中
  • 重定向
  • 读取新页面加载的会话值

ASP.NET就是这样一种后端语言.ASP.NET会话通过以下方式将会话绑定到用户:1)在第一次点击服务器时创建会话; 2)获取session_id并设置浏览器会话(仅在浏览器会话处于活动状态时有效,关闭浏览器和cookie被删除).这样对服务器的每个"请求",都会为sessions_id读取cookie,从数据存储中获取cookie,并填充Session用户var.

就个人而言,我从来没有在Go中复制过这个功能.但是,有人可以.

注意,这确实是完成保护"秘密"令牌的唯一方法,如果它是秘密的话.然后,人们可以窃取session_id并冒充请求.然后,人们可以实施一个4-way browser fingerprint来帮助限制模仿.然后,如果一个人能够嗅到具有该cookie的cookie session_id,那么他们将能够嗅探指纹方法的所有参数(除了IP!).

临时Cookie

我个人最喜欢的是将值存储在tmp浏览器会话cookie中,其值已过期Now() -1(意味着它将立即过期).这允许您在重定向的Web请求之前仅在浏览器在该请求之后使其到期之前读取cookie一次.

这是我从ASP.NET MVC中获取的一个技巧,我在所有控制器上强制执行(通过禁用Sessions并编写我自己的临时cookie处理程序).

请注意,它不会是私密/秘密:它将通过您的连接发送.即使是HTTPS,它仍然可以在浏览器的附加组件,cookie处理程序等中看到.是的,您可以"加密"该值,并在服务器端将其解密以确保安全性:但是,它只是强大的作为您的加密(并膨胀您的请求/响应大小).

好的'ol Querystring参数

不能打败:

/my/url?token=23462345345345
Run Code Online (Sandbox Code Playgroud)

既然你试图将它放入标题中,那么它无论如何都不是秘密.