Как обрабатывать сессии - PullRequest
2 голосов
/ 30 марта 2019

Я пытаюсь создать приложение, которое является внутренним интерфейсом Go, Angular front-end, размещенным на Google App Engine, которое вынуждает вас / входить в систему, если у вас нет сеанса или если ваш сеанс вошел в систему! = 1.

Я также пытаюсь использовать app.yaml для маршрутизации App Engine практически для всего.

Я не уверен, что это возможно?

Структура каталогов:

/myapp/app.yaml
/myapp/server/main.go
/myapp/client/(ANGULAR)

app.yaml (взято из: здесь ) приложение: myapp версия: 1 время выполнения: go111 #api_version: go1 главная: ./server

- url: /go/.* #Anything that goes to the golang app
  script: _go_app

# Routing for bundles to serve directly
- url: /((?:inline|main|polyfills|styles|vendor)\.[a-z0-9]+\.bundle\.js)
  secure: always
  redirect_http_response_code: 301
  static_files: client/app/dist/\1
  upload: client/app/dist/.*

# Routing for a prod styles.bundle.css to serve directly
- url: /(styles\.[a-z0-9]+\.bundle\.css)
  secure: always
  redirect_http_response_code: 301
  static_files: client/app/dist/\1
  upload: client/app/dist/.*

# Routing for typedoc, assets and favicon.ico to serve directly
- url: /((?:assets|docs)/.*|favicon\.ico)
  secure: always
  redirect_http_response_code: 301
  static_files: client/app/dist/\1
  upload: client/app/dist/.*

# Any other requests are routed to index.html for angular to handle so we don't need hash URLs
- url: /.*
  #secure: always
  redirect_http_response_code: 301
  static_files: client/app/dist/index.html
  upload: client/app/dist/index\.html
  #http_headers:
  #  Strict-Transport-Security: max-age=31536000; includeSubDomains
  #  X-Frame-Options: DENY

Таким образом, маршруты в / go будут действовать как api ... CRUD. Все остальное пошло бы на Angular.

Так как я могу проверить, есть ли сеанс? Я сомневаюсь, что это возможно в app.yaml. Если сделан вызов NOT to / go, нет реального сервера, который бы мог сказать, есть ли сеанс.

Итак, я просто не могу сделать это таким образом? Должен ли я использовать маршрутизацию Go, чтобы каждый вызов мог иметь проверку сеанса?

1 Ответ

2 голосов
/ 02 апреля 2019

Да, вы правильно догадались.Файлы / папки, помеченные как статические, обслуживаются отдельно от вашего приложения Go (с использованием сети доставки контента Google) и поэтому не могут знать идентификаторы и состояния сеансов вашего приложения Go.

Это проблема для вас?Обычно статические файлы (например, файлы HTML, CSS и JavaScript) могут быть доставлены без авторизации / аутентификации, они не представляют угрозы безопасности.

Если вы не хотите делать ваши статические файлы «общедоступными»,Вы должны использовать приложение Go, чтобы обслуживать их.Не помечайте их как статические и используйте любой из механизмов обслуживания файлов стандартной библиотеки Go (например, http.FileServer(), http.ServeFile() или http.ServeContent()).Используйте шаблон промежуточного программного обеспечения для проверки существования сеанса, и, если он существует, только после этого вызовите файловый сервер.

(Или реализуйте обслуживание статического контента самостоятельно, и вы можете делать все, что захотите/ need в ваших собственных обработчиках.)

Например, чтобы обслуживать "защищенные" файлы из Go, сопоставленные с /protected, и иметь некоторые "настоящие" статические файлы (обслуживаемые Google автоматически), сопоставленные с /static, это может выглядеть так:

app.yaml:

- url: /protected/.*
  script: _go_app

- url: /static
  static_dir: static

Тогда в вашем источнике Go вы можете подавать «защищенные» файлы следующим образом:

func init() {
    fileHandler := http.StripPrefix("/protected",
        http.FileServer(http.Dir("protected")))

    http.HandleFunc("/protected/", func(w http.ResponseWriter, r *http.Request) {
        // You may check if a session exists here
        sessExists := ...

        if !sessExists {
            http.Error(w, "you must login first", http.StatusUnauthorized)
            return
        }

        // Serve the requested file:
        fileHandler.ServeHTTP(w, r)
    })
}

Приведенная выше функция init() регистрирует обработчик, который обрабатывает пути с префиксом /protected/, и, если сеанс существует (эта логика принадлежит вам), он вызывает файловый сервер, который обслуживает содержимое папки protected.Обслуживаемый файл получен из пути, префикс /protected удален.Например, путь /protected/secret.txt будет обозначать файл protected/secret.txt.

...