duangao7133 2019-03-24 11:15
浏览 46
已采纳

在golang中未调用http.Handler

I have the following middleware, first sets currentUser in gorilla/context to current user acquired from database, and the second checks if currentUser exists and redirects otherwise:

package main

import (
    "database/sql"
    "github.com/gorilla/context"
    "log"
    "net/http"
    "server/helpers"
)

func withCurrentUser(db *sql.DB, next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        userId := helpers.GetCurrentUserId(db, r)

        if userId == nil {
            next.ServeHTTP(w, r)
            return
        }

        row := db.QueryRow("SELECT username FROM User WHERE id=?", userId)
        var username string

        switch err := row.Scan(&username); err {
        case sql.ErrNoRows:
            next.ServeHTTP(w, r)
            return
        case nil:
            user := helpers.User{UserId: *userId, LoggedIn: true, Username: username}
            context.Set(r, "currentUser", user)
        default:
            log.Fatal(err)
        }

        next.ServeHTTP(w, r)
    })
}

func loginRequired(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        user, ok := context.Get(r, "currentUser").(helpers.User)
        log.Println(user, ok)
        if !ok {
            http.Redirect(w, r, "/login", 301)
            return
        }
        next.ServeHTTP(w, r)
    })
}

Then when I register a route that requires authenticated user, I do the following:

router.Handle("/create_post",
        withCurrentUser(db, loginRequired(http.HandlerFunc(createPostGet))),
    ).Methods(http.MethodGet)

Where createPostGet:

func createPostGet(w http.ResponseWriter, r *http.Request) {
    tmpl := template.Must(template.ParseFiles("templates/createPost.html"))
    user := context.Get(r, "currentUser").(helpers.User)
    _ = tmpl.Execute(w, helpers.FormStruct{CurrentUser: user})
}

My problem is: even if user is authenticated and context is populated correctly, this route always redirects to login. I tried setting breakpoints inside loginRequired and adding log.Println (as you can see in code), and that function doesn't seem to be even called (no breakpoints stop, no log output, too).

What's happening and how to make sure loginRequired is called every time and checks context properly?

UPD: It doesn't seem to persist, I recompiled the app a few times and now it's working. Anyway, what might be the reason for such behavior (I'm positive I saved everything the first time).

UPD 2: I found out that the problem is connected to browser caching, but I still have no idea why it happens. When I disable browser caching, everything works and function is called every time, but while browser cache is enabled, the function isn't called at all. Any ideas?

  • 写回答

1条回答 默认 最新

  • douzhouhan4618 2019-03-24 16:55
    关注

    OMG, that was stupid. I was using 301 redirect code in loginRequired, so redirect was permanent and browser didn't even make requests.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?