我正在尝试构建一个托管在Google AppEngine上的Go后端,Angular前端的应用程序,如果您没有会话或会话的登录状态为=1,则会强制您登录/ login。
我还尝试对几乎所有内容使用App Engine的app.yaml路由。
我不确定这可能吗?
目录结构:
/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。其他一切将归于Angular。
因此,我如何检查是否有会议?我怀疑在app.yaml中是否可能。如果没有调用/ go,则没有真正的服务器告诉它是否存在会话。
那么,我是否不可能以这种方式这样做?是否需要使用Go的路由,以便每个呼叫都可以进行会话检查?
是的,您猜对了。标记为静态的文件/文件夹是与Go应用分开提供的(使用Google的内容传输网络),因此无法知道Go应用的会话ID和状态。
对您来说有问题吗?通常,静态文件(例如HTML,CSS和JavaScript文件)可以在未经授权/身份验证的情况下交付,它们不会带来安全风险。
如果您不想让静态文件“公开”,则必须使用Go应用程序来提供这些文件。不要将它们标记为静态的,并且使用任何服务Go的标准库的机制的文件(例如http.FileServer(),http.ServeFile()或http.ServeContent())。使用中间件模式检查会话是否存在,如果存在,则仅调用文件服务器。
http.FileServer()
http.ServeFile()
http.ServeContent()
(或自行实现提供静态内容的服务,您可以在自己的处理程序中做任何您想做/需要做的事情。)
例如,要将Go中的“受保护”文件映射到/protected,并将某些“真实”静态文件(由Google自动提供)映射到/static,则可能看起来像这样:
/protected
/static
app.yaml:
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文件。
init()
/protected/
protected
/protected/secret.txt
protected/secret.txt