使用 Nosurf 和 A​​ppengine Blobstore 时出现 HTTP 400

HTTP 400 When Using Nosurf and Appengine Blobstore

我正在使用 Appengine Blob 存储 example and it works fine (I modified to take two files but that is not the issue). However, when I turn on nosurf 它给了我一个 HTTP 400。我将 csrf 令牌传递给我的表单。即使我只上传一个文件,问题也存在。

nosurf 适用于其他形式,但只会给我上传 blobstore 文件带来麻烦。

由于代码很大(这只是一些小调整的例子),我把它放在这里:http://play.golang.org/p/SJADmn-WvJ(当然你不能运行它在那里,因为你需要应用程序-engine 和 nosurf)

小部分代码:

const rootTemplateHTML = `
<html><body>
<form action="{{.UpUrl}}" method="POST" enctype="multipart/form-data">
    Upload File: <input type="file" name="file1"><br>
    Upload File: <input type="file" name="file2"><br>
    <input type="hidden" name="csrf_token" value="{{ .Token }}">
    <input type="submit" name="submit" value="Submit">
</form>
</body></html>
`

这不起作用:

    http.Handle("/", nosurf.New(http.HandlerFunc(handleRoot)))
    http.Handle("/upload", nosurf.New(http.HandlerFunc(handleUpload)))
    http.HandleFunc("/serve/", handleServe)

但这有效(无 400 状态):

    http.HandleFunc("/", handleRoot)
    http.HandleFunc("/serve/", handleServe)
    http.HandleFunc("/upload", handleUpload)

这与nosurfapp-engine有关吗?关于我应该如何解决这个问题有什么建议吗?

谢谢!

Blobstore 上传 URL 的工作原理是将您上传的文件实际发布到您应用上的特殊 /_ah/... 路由,该路由实际上并未由您的应用处理,但用作基础设施的信号将数据发送到存储上传处理程序,这是一个内部处理程序,用于实际存储。

您传递给生成上传的函数的回调路由 URL 是您应用程序上的路由,一旦完成,该路由将收到一个请求,该请求不包含文件数据,但包含文件元数据,例如文件名,以及传递给请求的任何其他参数(例如重要的 CSRF 令牌)。

但是,您传递的令牌是通过调用 nosurf.Token(r) 生成的,其中 r 用户浏览器在页面已生成。当存储上传处理程序将回调请求发送到您的 /upload 路由时,nosurf 期望发送请求的客户端具有为 该客户端 生成的有效 CSRF 令牌(存储上传处理程序)并根据该期望验证该请求。相反,它会收到为您最初发送给用户的页面生成的 CSRF 令牌,其中包含表单。