У меня есть следующее промежуточное ПО, сначала устанавливается currentUser
в gorilla/context
для текущего пользователя, полученного из базы данных, а второй проверяет, существует ли currentUser
, и перенаправляет иначе:
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)
})
}
Затем, когда я регистрирую маршрут, требующий аутентифицированного пользователя, я делаю следующее:
router.Handle("/create_post",
withCurrentUser(db, loginRequired(http.HandlerFunc(createPostGet))),
).Methods(http.MethodGet)
Где 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})
}
Моя проблема: даже если пользователь аутентифицирован и контекст заполнен правильно, этот маршрут всегда перенаправляет на вход в систему. Я попытался установить точки останова внутри loginRequired
и добавить log.Println
(как вы можете видеть в коде), и эта функция, кажется, даже не вызывается (остановка без останова, и вывод журнала тоже).
Что происходит и как убедиться, что loginRequired
вызывается каждый раз и правильно проверяет контекст?
UPD: Кажется, что оно не сохраняется, я перекомпилировал приложение несколько раз, и теперь оно работает. Во всяком случае, в чем может быть причина такого поведения (я уверен, я все сперва сохранил).
UPD 2: Я обнаружил, что проблема связана с кэшированием браузера, но я до сих пор не понимаю, почему это происходит. Когда я отключаю кеширование браузера, все работает, и функция вызывается каждый раз, но, хотя кеш браузера включен, функция вообще не вызывается. Есть идеи?