【问题标题】:How do I pass the app around function?如何传递应用程序的功能?
【发布时间】:2018-06-18 07:02:27
【问题描述】:

main 中,应用程序是这样启动的:

// ...

func main () {
    initializeAppDefault()
    go lib.GetData()
    http.HandleFunc("/_ah/somepoint", lib.SomeHandler)
// .. 

func initializeAppDefault() *firebase.App {
    // [START initialize_app_default]
    app, err := firebase.NewApp(context.Background(), nil)
    if err != nil {
        log.Fatalf("error initializing app: %v\n", err)
    }
    // [END initialize_app_default]
    return app
}

SomeHandler 中,我需要initializeAppDefault 返回的应用程序来验证JSON Web Token(JWT)。

func SomeHandler(w http.ResponseWriter, r *http.Request) {
    // Set content type:
    w.Header().Set("Content-Type", "application/json")

    if r.Header != nil {
        ReqToken := r.Header.Get("Authorization")
        splitToken := strings.Split(ReqToken, "Bearer")
        ReqToken = splitToken[1]
        fmt.Println(ReqToken)
        // Verify JWT
        // If it's invalid, return?

        verifyIDToken(app, ReqToken)
        // How do I pass the app in here?

func verifyIDToken(app *firebase.App, idToken string) *auth.Token {
// ... 

我的问题是,当通过调用initializeAppDefault()main.go 文件中初始化应用程序时,如何将其传递给处理/_ah/somepoint 处的请求的SomeHandler

【问题讨论】:

  • 我不确定您所说的“传递应用程序”是什么意思。 “App”通常是指编译后的程序,以及任何支持文件。这不是可以“传递”的东西。
  • 好吧,很公平;但是我的问题仍然存在,那么我将如何在处理程序中引用它呢?我是 Go 新手。对不起,如果这是一个愚蠢的问题。
  • 将参数传递给处理程序的正常方法是让它返回一个闭包给实际的处理程序。
  • 函数verifyIDTokenapp *firebase.App 作为两个输入之一,另一个是idToken 本身。我应该从SomeHandler 向这个函数传递什么来验证令牌(在ReqToken 中)?
  • 在我调用verifyIDToken 的行中,我需要以某种方式传递“应用程序”。我在问我如何从上下文中得到它来传递它?

标签: firebase google-app-engine go firebase-authentication jwt


【解决方案1】:

将任意依赖项传递给 HTTP 处理函数的方法是返回一个闭包:

func myHandler(a *Something, b *SomethingElse) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // The body of the handler here, using a and b
    }
}

然后你将它用作:

http.Handle("/some/path", myHandler(a, b))

【讨论】:

  • 在我的例子中,你将如何使用你自己的例子从initializeAppDefault() 传递返回值?
  • x := initializeAppDefault(); /* ... */ myHandler(x)
  • 谢谢。学到很多:)
【解决方案2】:

使用*firebase.App 的成员定义新的结构类型:

type myapp struct {
    fbapp *firebase.App
    // here can be other common states and resources
    // like sessions, db connections, etc...
}

将您的处理程序定义为该类型的方法

func (ma *myapp) SomeHandler(w http.ResponseWriter, r *http.Request) {
    // here you have access to all members of myapp, including ma.fbapp
    // also you can use your lib.* funcs here
}

在您的主目录中,您需要创建myapp 并将其传递给http.HandleFunc

func main () {
    ma := &myapp{
        fbapp: initializeAppDefault()
    }
    go lib.GetData()
    http.HandleFunc("/_ah/somepoint", ma.SomeHandler)

这是一种常见的模式。看看我是如何使用它的 in my interview task:注意处理程序是如何定义的,how they getting access to the common s.storehow main function inits all common resources, creates router and runs it

【讨论】:

  • 当我使用 SomeHandler 的语法时,即使导入了 lib,我也无法在 main 函数中访问它。怎么会?
  • @cbll 你的意思是“失去访问”?你能展示更多你的代码吗?
  • 我不得不将 SomeHandler 移动到调用 main 的 main.go 中。我不能再使用lib.Somehandler,它无法从lib 包中识别它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
相关资源
最近更新 更多