2017-01-16 10 views
0

Я новичок в разработке веб-приложений. Я работаю с golang и хотел бы безопасно загружать загруженные пользователем файлы, например, позволяя им просматривать только свои собственные файлы.Как безопасно обслуживать файл в golang

Теперь я сохранил эти файлы в локальной файловой системе со случайными именами. Если я обслуживаю весь каталог, злонамеренные пользователи могут просматривать файлы других пользователей. Это звучит как обычный прецедент, интересно, какой у него лучший подход?

+0

Вместо того, чтобы обслуживать их непосредственно с веб-сервера напрямую, просто добавьте на маршруте слой проверки, который пользователь попросит увидеть один из его файлов. –

+0

вы можете использовать 'http.ServeFile()' для обслуживания файла. Разумеется, с некоторой логикой контроллера –

ответ

2

Этот вопрос должен быть довольно расплывчатым и архитектурным решением для оптимизации доступа к данным и защиты файлов.

Однако, это простое решение, которое может служить вашему прецеденту.

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.

+0

как вы можете префикс в этом случае? – Apophis

0

Если ur filenames являются случайными и достаточно длинными, и использовать безопасный случайный генератор, это уже безопасно (если каталог не включен) с некоторыми ограничениями.

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

Один пользователь будет иметь доступ к файлу, только если он имеет URL с произвольным именем. Ограничение заключается в том, что URL-адрес будет сохранен в истории браузера, если кто-то еще обнаружит, что он также получит к нему доступ.

 Смежные вопросы

  • Нет связанных вопросов^_^