使用Nosurf和Appengine Blobstore时的HTTP 400

时间:2015-02-01 08:31:14

标签: google-app-engine go

我正在使用Appengine Blob商店example,它运行正常(我修改了两个文件,但这不是问题)。但是,当我打开nosurf时,它会给我一个HTTP 400。我将csrf令牌传递给我的表单。即使我只上传一个文件,问题仍然存在。

nosurf适用于其他表单,但只会让我无法使用blobstore文件上传。

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

代码的一小部分:

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有关吗?关于我应该怎么做才能解决这个问题的任何建议?

谢谢!

1 个答案:

答案 0 :(得分:1)

blobstore上传网址的工作原理是将您的文件上传实际发布到应用上的特殊/_ah/...路线,该路线实际上并非由您的应用处理,而是用作基础设施发送数据的信号。存储上传处理程序,它是执行实际存储的内部处理程序。

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

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