我是新开发web应用程序。我正在与golang合作,并希望安全地为用户上传的文件提供服务,例如只允许他们查看他们自己的文件。你如何在golang中安全地提供文件
现在我已经将这些文件保存到具有随机名称的本地文件系统。如果我服务整个目录,恶意用户可能会查看其他用户文件。这听起来像是一个常见用例,我想知道处理它的最佳方法是什么?
我是新开发web应用程序。我正在与golang合作,并希望安全地为用户上传的文件提供服务,例如只允许他们查看他们自己的文件。你如何在golang中安全地提供文件
现在我已经将这些文件保存到具有随机名称的本地文件系统。如果我服务整个目录,恶意用户可能会查看其他用户文件。这听起来像是一个常见用例,我想知道处理它的最佳方法是什么?
这个问题非常模糊,而且架构决策必须优化数据访问并保护文件。
但是,下面是一个简单的解决方案,可以用于您的用例。
package main
import (
"fmt"
"mime"
"net/http"
"path/filepath"
)
//UserFilesMap is the map that contains
var UserFilesMap map[string]FilePermission
type FilePermission map[string]struct{}
//FileServer is the function that serves files
func FileServer(w http.ResponseWriter, r *http.Request) {
//get the file path the user wants to access
filename := r.URL.Path[9:]
var uname, pass string
var ok bool
if uname, pass, ok = r.BasicAuth(); !ok {
w.WriteHeader(http.StatusForbidden)
return
}
if !(uname == "user" && pass == "1234") {
w.WriteHeader(http.StatusForbidden)
return
}
//Checking if user has permission to the file
if _, ok := UserFilesMap[uname][filename]; !ok {
w.WriteHeader(http.StatusForbidden)
return
}
w.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(filename)))
http.ServeFile(w, r, "files/"+filename)
}
func main() {
UserFilesMap = make(map[string]FilePermission)
// UserFilesMap["user"] = FilePermission{"xyz.txt": struct{}{}}
UserFilesMap["user"] = FilePermission{"abc.txt": struct{}{}}
http.HandleFunc("/getFile/", FileServer)
if err := http.ListenAndServe(":8080", nil); err != nil {
fmt.Println("Error in ListenAndServe")
}
}
在这里,我用地图来存储文件的权限。我建议你改为使用SQL表。
在这种情况下,你如何去掉前缀? – Apophis
如果你的文件名是随机的,足够长,并使用安全的随机生成器,这已经是安全的(除非目录列表已启用),但有一些限制。
https://golang.org/pkg/crypto/rand/
一个用户将只能访问,如果他有与随机名称的URL文件。限制是,尽管URL将被保存在浏览器历史记录中,但如果其他人发现它也可以访问它。
只需在用户要求查看其文件之一的路线上添加验证层,而不是直接从网络服务器提供它们。 –
你可以使用'http.ServeFile()'来提供一个文件。有些控制器逻辑当然是 –