From 126ccfa715740407c562faa36b2947b3f0f811af Mon Sep 17 00:00:00 2001 From: lbenedar Date: Fri, 6 Mar 2026 15:37:31 +0300 Subject: [PATCH] ch12.2 --- cmd/web/context.go | 5 +++++ cmd/web/helpers.go | 6 +++++- cmd/web/middleware.go | 39 +++++++++++++++++++++++++++++++-------- cmd/web/routes.go | 2 +- internal/models/users.go | 8 +++++++- 5 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 cmd/web/context.go diff --git a/cmd/web/context.go b/cmd/web/context.go new file mode 100644 index 0000000..01d1722 --- /dev/null +++ b/cmd/web/context.go @@ -0,0 +1,5 @@ +package main + +type contextKey string + +const isAuthenticatedContextKey = contextKey("isAuthenticated") diff --git a/cmd/web/helpers.go b/cmd/web/helpers.go index 6f57daf..550cee5 100644 --- a/cmd/web/helpers.go +++ b/cmd/web/helpers.go @@ -42,5 +42,9 @@ func (app *application) decodePostForm(r *http.Request, snippetForm any) error { } func (app *application) isAuthenticated(r *http.Request) bool { - return app.sessionManager.Exists(r.Context(), "authenticatedUserID") + isAuthenticated, ok := r.Context().Value(isAuthenticatedContextKey).(bool) + if !ok { + return false + } + return isAuthenticated } diff --git a/cmd/web/middleware.go b/cmd/web/middleware.go index e1e4ef6..595ef60 100644 --- a/cmd/web/middleware.go +++ b/cmd/web/middleware.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "net/http" @@ -20,6 +21,17 @@ func secureHeaders(next http.Handler) http.Handler { }) } +func noSurf(next http.Handler) http.Handler { + csrfHanlder := nosurf.New(next) + csrfHanlder.SetBaseCookie(http.Cookie{ + HttpOnly: true, + Path: "/", + Secure: true, + }) + + return csrfHanlder +} + func (app *application) logRequest(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { app.infoLog.Printf("%s - %s %s %s", r.RemoteAddr, r.Proto, r.Method, r.URL.RequestURI()) @@ -52,13 +64,24 @@ func (app *application) requireAuthentication(next http.Handler) http.Handler { }) } -func noSurf(next http.Handler) http.Handler { - csrfHanlder := nosurf.New(next) - csrfHanlder.SetBaseCookie(http.Cookie{ - HttpOnly: true, - Path: "/", - Secure: true, - }) +func (app *application) authenticate(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + id := app.sessionManager.GetInt(r.Context(), "authenticatedUserID") + if id == 0 { + next.ServeHTTP(w, r) + return + } - return csrfHanlder + exists, err := app.users.Exists(id) + if err != nil { + app.serverError(w, err) + return + } + + if exists { + ctx := context.WithValue(r.Context(), isAuthenticatedContextKey, true) + r = r.WithContext(ctx) + } + next.ServeHTTP(w, r) + }) } diff --git a/cmd/web/routes.go b/cmd/web/routes.go index bb1ffa3..14b92c5 100644 --- a/cmd/web/routes.go +++ b/cmd/web/routes.go @@ -17,7 +17,7 @@ func (app *application) routes() http.Handler { fileServer := http.FileServer(http.Dir("./ui/static/")) router.Handler(http.MethodGet, "/static/*filepath", http.StripPrefix("/static", fileServer)) - dynamic := alice.New(app.sessionManager.LoadAndSave, noSurf) + dynamic := alice.New(app.sessionManager.LoadAndSave, noSurf, app.authenticate) router.Handler(http.MethodGet, "/", dynamic.ThenFunc(app.home)) router.Handler(http.MethodGet, "/snippet/view/:id", dynamic.ThenFunc(app.snippetView)) diff --git a/internal/models/users.go b/internal/models/users.go index 7b6196c..4927c2f 100644 --- a/internal/models/users.go +++ b/internal/models/users.go @@ -69,5 +69,11 @@ func (m *UserModel) Authenticate(email, password string) (int, error) { } func (m *UserModel) Exists(id int) (bool, error) { - return false, nil + var exists bool + + stmt := `SELECT EXISTS(SELECT true FROM users WHERE id = ?)` + + err := m.DB.QueryRow(stmt, id).Scan(&exists) + + return exists, err }