我正在使用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)
这与nosurf
或app-engine
有关吗?关于我应该怎么做才能解决这个问题的任何建议?
谢谢!
答案 0 :(得分:1)
blobstore上传网址的工作原理是将您的文件上传实际发布到应用上的特殊/_ah/...
路线,该路线实际上并非由您的应用处理,而是用作基础设施发送数据的信号。存储上传处理程序,它是执行实际存储的内部处理程序。
您传递给生成上传URL的函数的回调路由是您的应用程序上的路由,该路由将在完成后接收请求,该请求不包含文件数据,但包含文件元数据(如文件名)以及任何文件元数据传递给请求的其他参数(例如,重要的是CSRF令牌)。
但是,您传递的令牌是通过调用nosurf.Token(r)
生成的,其中r
是用户浏览器在生成页面时对您的应用程序进行的请求 / em>的。当存储上载处理程序将回调请求发送到您的/upload
路由时,nosurf希望发送请求的客户端具有为该客户端(存储上载处理程序)生成的有效CSRF令牌,并且根据该期望验证该请求。相反,它会收到为您最初发送给用户的页面生成的CSRF令牌,该令牌包含表单。