你如何安全地在golang中提供文件

时间:2017-01-16 19:45:38

标签: go web-applications

我是开发Web应用程序的新手。我正在使用golang并希望安全地提供用户上传的文件,例如允许他们仅查看自己的文件。

现在我已将这些文件保存到具有随机名称的本地文件系统。如果我服务整个目录,恶意用户可能会查看其他用户文件。这听起来像是一个常见的用例,我想知道处理它的最佳方法是什么?

2 个答案:

答案 0 :(得分:3)

必须在非常模糊和架构决策中提出这个问题,以优化数据访问并保护文件。

但是,这是一个可能为您的用例提供服务的简单解决方案。

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表。

答案 1 :(得分:0)

如果您的文件名是随机且足够长并且使用安全的随机生成器,那么这已经是安全的(除非启用了目录列表)但是有一些限制。

https://golang.org/pkg/crypto/rand/

一个用户只有拥有随机名称的网址才能访问该文件。限制是,URL将保存在浏览器历史记录中,如果其他人发现它,他也可以访问它。