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.

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

报告相同问题?

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog