Optimize CurrentUser to read from DB only once per request
This commit is contained in:
parent
748adeb289
commit
967e149875
|
@ -1,6 +1,7 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -46,7 +47,9 @@ func LoginRequired(handler http.Handler) http.Handler {
|
|||
}
|
||||
}
|
||||
|
||||
handler.ServeHTTP(w, r)
|
||||
// Stick the CurrentUser in the request context so future calls to session.CurrentUser can read it.
|
||||
ctx := context.WithValue(r.Context(), session.CurrentUserKey, user)
|
||||
handler.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -55,19 +58,26 @@ func AdminRequired(handler http.Handler) http.Handler {
|
|||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// User must be logged in.
|
||||
if currentUser, err := session.CurrentUser(r); err != nil {
|
||||
currentUser, err := session.CurrentUser(r)
|
||||
if err != nil {
|
||||
log.Error("AdminRequired: %s", err)
|
||||
errhandler := templates.MakeErrorPage("Login Required", "You must be signed in to view this page.", http.StatusForbidden)
|
||||
errhandler.ServeHTTP(w, r)
|
||||
return
|
||||
} else if !currentUser.IsAdmin {
|
||||
}
|
||||
|
||||
// Stick the CurrentUser in the request context so future calls to session.CurrentUser can read it.
|
||||
ctx := context.WithValue(r.Context(), session.CurrentUserKey, currentUser)
|
||||
|
||||
// Admin required.
|
||||
if !currentUser.IsAdmin {
|
||||
log.Error("AdminRequired: %s", err)
|
||||
errhandler := templates.MakeErrorPage("Admin Required", "You do not have permission for this page.", http.StatusForbidden)
|
||||
errhandler.ServeHTTP(w, r)
|
||||
errhandler.ServeHTTP(w, r.WithContext(ctx))
|
||||
return
|
||||
}
|
||||
|
||||
handler.ServeHTTP(w, r)
|
||||
handler.ServeHTTP(w, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,12 @@ import (
|
|||
func CurrentUser(r *http.Request) (*models.User, error) {
|
||||
sess := Get(r)
|
||||
if sess.LoggedIn {
|
||||
// Did we already get the CurrentUser once before?
|
||||
ctx := r.Context()
|
||||
if user, ok := ctx.Value(CurrentUserKey).(*models.User); ok {
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// Load the associated user ID.
|
||||
return models.GetUser(sess.UserID)
|
||||
}
|
||||
|
|
|
@ -26,8 +26,9 @@ type Session struct {
|
|||
}
|
||||
|
||||
const (
|
||||
ContextKey = "session"
|
||||
CSRFKey = "csrf"
|
||||
ContextKey = "session"
|
||||
CurrentUserKey = "current_user"
|
||||
CSRFKey = "csrf"
|
||||
)
|
||||
|
||||
// New creates a blank session object.
|
||||
|
|
Reference in New Issue
Block a user