【问题标题】:prevent access to files in folder with a golang server防止使用 golang 服务器访问文件夹中的文件
【发布时间】:2016-11-21 09:34:27
【问题描述】:

我有一个在 golang 中处理文件夹路径的服务器:

fs := http.FileServer(http.Dir("./assets"))
http.Handle("/Images/", fs)
http.ListenAndServe(":8000", nil)

但是在这个文件夹中有私人图像,应该无法访问文件。那么如何保护图像访问并防止任何人访问文件夹的内容。

例如:

【问题讨论】:

标签: go server


【解决方案1】:

如果您想使用http 包阻止目录,也许这对您有用:

https://groups.google.com/forum/#!topic/golang-nuts/bStLPdIVM6w

package main

import (
  "net/http"
  "os"
)

type justFilesFilesystem struct {
  fs http.FileSystem
}

func (fs justFilesFilesystem) Open(name string) (http.File, error) {
  f, err := fs.fs.Open(name)
  if err != nil {
      return nil, err
  }
  return neuteredReaddirFile{f}, nil
}

type neuteredReaddirFile struct {
  http.File
}

func (f neuteredReaddirFile) Readdir(count int) ([]os.FileInfo, error) {
  return nil, nil
}

func main() {
  fs := justFilesFilesystem{http.Dir("/tmp/")}
  http.ListenAndServe(":8080", http.FileServer(fs))
}

【讨论】:

  • 但是我应该如何处理这一行:fs := http.FileServer(http.Dir("./assets")) ??
  • 我认为您必须将 http.Dir("/tmp/") 替换为 http.Dir("./assets")
  • 好吧,它工作得很好,但是我在这个服务器上的 api 不再工作,所以我应该做 2 个服务器吗?
  • 我不知道你的服务器是如何工作的,我不能告诉你你应该或不应该有第二台服务器。也许尝试关闭此问题并打开一个新问题来解释您的新问题!
【解决方案2】:

FileServer() 上的一个小包装解决了您的问题,现在您必须添加某种逻辑来进行授权,看起来您有唯一的名称,这很好,所以我只是为您过滤图像名称来创建地图名称,现在你可以添加一些更动态的东西,比如 key/store(memcached,redis。等)希望你能关注 cmets

package main

import (
    "log"
    "net/http"
    "strings"
)

// put the allowed hashs or keys here
// you may consider put them in a key/value store
//
var allowedImages = map[string]bool{
    "key-abc.jpg": true,
    "key-123.jpg": true,
}

func main() {

    http.Handle("/Images/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        // here we can do any kind of checking, in this case we'll just split the url and
        // check if the image name is in the allowedImages map, we can check in a DB or something
        //
        parts := strings.Split(r.URL.Path, "/")
        imgName := parts[len(parts)-1]

        if _, contains := allowedImages[imgName]; !contains { // if the map contains the image name

            log.Printf("Not found image: %q path: %s\n", imgName, r.URL.Path)

            // if the image is not found we write a 404
            //
            // Bonus: we don't list the directory, so nobody can know what's inside :)
            //
            http.NotFound(w, r)
            return
        }

        log.Printf("Serving allowed image: %q\n", imgName)

        fileServer := http.StripPrefix("/Images/", http.FileServer(http.Dir("./assets")))

        fileServer.ServeHTTP(w, r) // StripPrefix() and FileServer() return a Handler that implements ServerHTTP()
    }))

    http.ListenAndServe(":8000", nil)
}

https://play.golang.org/p/ehrd_AWXim

【讨论】:

  • 这不是我需要知道的,但是谢谢,我相信有一天我会需要这个例子 :)
猜你喜欢
  • 2023-01-28
  • 1970-01-01
  • 2011-03-25
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
  • 1970-01-01
相关资源
最近更新 更多