diff --git a/cmd/web/middleware.go b/cmd/web/middleware.go index 2fc5cae..e1e4ef6 100644 --- a/cmd/web/middleware.go +++ b/cmd/web/middleware.go @@ -3,6 +3,8 @@ package main import ( "fmt" "net/http" + + "github.com/justinas/nosurf" ) func secureHeaders(next http.Handler) http.Handler { @@ -49,3 +51,14 @@ func (app *application) requireAuthentication(next http.Handler) http.Handler { next.ServeHTTP(w, r) }) } + +func noSurf(next http.Handler) http.Handler { + csrfHanlder := nosurf.New(next) + csrfHanlder.SetBaseCookie(http.Cookie{ + HttpOnly: true, + Path: "/", + Secure: true, + }) + + return csrfHanlder +} diff --git a/cmd/web/routes.go b/cmd/web/routes.go index 08786a6..bb1ffa3 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) + dynamic := alice.New(app.sessionManager.LoadAndSave, noSurf) router.Handler(http.MethodGet, "/", dynamic.ThenFunc(app.home)) router.Handler(http.MethodGet, "/snippet/view/:id", dynamic.ThenFunc(app.snippetView)) diff --git a/cmd/web/templates.go b/cmd/web/templates.go index 3667346..b115051 100644 --- a/cmd/web/templates.go +++ b/cmd/web/templates.go @@ -7,6 +7,7 @@ import ( "time" "gitea.local.lab/Lbenedar/snippetbox/internal/models" + "github.com/justinas/nosurf" ) type templateData struct { @@ -16,6 +17,7 @@ type templateData struct { Form any Flash string IsAuthenticated bool + CSRFToken string } func humanDate(t time.Time) string { @@ -31,6 +33,7 @@ func (app *application) newTemplateData(r *http.Request) *templateData { CurrentYear: time.Now().Year(), Flash: app.sessionManager.PopString(r.Context(), "flash"), IsAuthenticated: app.isAuthenticated(r), + CSRFToken: nosurf.Token(r), } } diff --git a/go.mod b/go.mod index 6f85f10..a650329 100644 --- a/go.mod +++ b/go.mod @@ -10,5 +10,6 @@ require ( github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/justinas/alice v1.2.0 // indirect + github.com/justinas/nosurf v1.2.0 // indirect golang.org/x/crypto v0.48.0 // indirect ) diff --git a/go.sum b/go.sum index 644b54c..a774b89 100644 --- a/go.sum +++ b/go.sum @@ -13,5 +13,7 @@ github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4d github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo= github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= +github.com/justinas/nosurf v1.2.0 h1:yMs1bSRrNiwXk4AS6n8vL2Ssgpb9CB25T/4xrixaK0s= +github.com/justinas/nosurf v1.2.0/go.mod h1:ALpWdSbuNGy2lZWtyXdjkYv4edL23oSEgfBT1gPJ5BQ= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= diff --git a/ui/html/pages/create.tmpl b/ui/html/pages/create.tmpl index 850e94b..f18a4f4 100644 --- a/ui/html/pages/create.tmpl +++ b/ui/html/pages/create.tmpl @@ -2,6 +2,7 @@ {{define "main"}}
+
{{with .Form.FieldErrors.title}} diff --git a/ui/html/pages/login.tmpl b/ui/html/pages/login.tmpl index c7d6e22..c382d95 100644 --- a/ui/html/pages/login.tmpl +++ b/ui/html/pages/login.tmpl @@ -2,6 +2,7 @@ {{define "main"}} + {{range .Form.NonFieldErrors}}
{{.}}
{{end}} diff --git a/ui/html/pages/signup.tmpl b/ui/html/pages/signup.tmpl index e883343..9b4e604 100644 --- a/ui/html/pages/signup.tmpl +++ b/ui/html/pages/signup.tmpl @@ -2,6 +2,7 @@ {{define "main"}} +
{{with .Form.FieldErrors.name}} diff --git a/ui/html/partials/nav.tmpl b/ui/html/partials/nav.tmpl index ad98808..2c06dab 100644 --- a/ui/html/partials/nav.tmpl +++ b/ui/html/partials/nav.tmpl @@ -9,6 +9,7 @@
{{if .IsAuthenticated}} + {{else}}