lets-go:11.7 CSRF
This commit is contained in:
parent
7db05bca1d
commit
1a59a9e720
@ -10,6 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-playground/form/v4"
|
"github.com/go-playground/form/v4"
|
||||||
|
"github.com/justinas/nosurf"
|
||||||
)
|
)
|
||||||
|
|
||||||
// newTemplateData ...
|
// newTemplateData ...
|
||||||
@ -18,6 +19,7 @@ func (app *application) newTemplateData(r *http.Request) templateData {
|
|||||||
CurrentYear: time.Now().Year(),
|
CurrentYear: time.Now().Year(),
|
||||||
Flash: app.sessionManager.PopString(r.Context(), "flash"),
|
Flash: app.sessionManager.PopString(r.Context(), "flash"),
|
||||||
IsAuthenticated: app.isAuthenticated(r),
|
IsAuthenticated: app.isAuthenticated(r),
|
||||||
|
CSRFToken: nosurf.Token(r),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/justinas/nosurf"
|
||||||
)
|
)
|
||||||
|
|
||||||
// logRequest ...
|
// logRequest ...
|
||||||
@ -59,3 +61,14 @@ func (app *application) requireAuthentication(next http.Handler) http.Handler {
|
|||||||
next.ServeHTTP(w, r)
|
next.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func noSurf(next http.Handler) http.Handler {
|
||||||
|
csrfHandler := nosurf.New(next)
|
||||||
|
csrfHandler.SetBaseCookie(http.Cookie{
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
Secure: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
return csrfHandler
|
||||||
|
}
|
||||||
|
@ -23,7 +23,7 @@ func (app *application) routes() http.Handler {
|
|||||||
fileServer := http.FileServer(http.Dir("./ui/static"))
|
fileServer := http.FileServer(http.Dir("./ui/static"))
|
||||||
router.Handler(http.MethodGet, "/static/*filepath", http.StripPrefix("/static", fileServer))
|
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, "/", dynamic.ThenFunc(app.home))
|
||||||
router.Handler(http.MethodGet, "/snippet/view/:id", dynamic.ThenFunc(app.snippetView))
|
router.Handler(http.MethodGet, "/snippet/view/:id", dynamic.ThenFunc(app.snippetView))
|
||||||
|
@ -15,6 +15,7 @@ type templateData struct {
|
|||||||
Form any
|
Form any
|
||||||
Flash string
|
Flash string
|
||||||
IsAuthenticated bool
|
IsAuthenticated bool
|
||||||
|
CSRFToken string
|
||||||
}
|
}
|
||||||
|
|
||||||
// humanDate ...
|
// humanDate ...
|
||||||
|
@ -9,5 +9,6 @@ require (
|
|||||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||||
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
github.com/julienschmidt/httprouter v1.3.0 // indirect
|
||||||
github.com/justinas/alice v1.2.0 // indirect
|
github.com/justinas/alice v1.2.0 // indirect
|
||||||
|
github.com/justinas/nosurf v1.1.1 // indirect
|
||||||
golang.org/x/crypto v0.19.0 // indirect
|
golang.org/x/crypto v0.19.0 // indirect
|
||||||
)
|
)
|
||||||
|
@ -11,5 +11,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/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 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo=
|
||||||
github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
|
github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
|
||||||
|
github.com/justinas/nosurf v1.1.1 h1:92Aw44hjSK4MxJeMSyDa7jwuI9GR2J/JCQiaKvXXSlk=
|
||||||
|
github.com/justinas/nosurf v1.1.1/go.mod h1:ALpWdSbuNGy2lZWtyXdjkYv4edL23oSEgfBT1gPJ5BQ=
|
||||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{{define "main"}}
|
{{define "main"}}
|
||||||
<form action='/snippet/create' method='POST'>
|
<form action='/snippet/create' method='POST'>
|
||||||
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
||||||
<div>
|
<div>
|
||||||
<label>Title:</label>
|
<label>Title:</label>
|
||||||
{{with .Form.FieldErrors.title}}
|
{{with .Form.FieldErrors.title}}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
{{define "title"}}Login{{end}}
|
{{define "title"}}Login{{end}}
|
||||||
|
|
||||||
{{define "main"}}
|
{{define "main"}}
|
||||||
<form action='/user/login' method='POST'>
|
<form action='/user/login' method='POST' novalidate>
|
||||||
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
||||||
{{range .Form.NonFieldErrors}}
|
{{range .Form.NonFieldErrors}}
|
||||||
<div class="error">{{.}}</div>
|
<div class="error">{{.}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
{{define "title"}}User Signup{{end}}
|
{{define "title"}}User Signup{{end}}
|
||||||
|
|
||||||
{{define "main"}}
|
{{define "main"}}
|
||||||
<form action='/user/signup' method='POST'>
|
<form action='/user/signup' method='POST' novalidate>
|
||||||
|
<input type="hidden" name"csrf_token" value="{{.CSRFToken}}"
|
||||||
<div>
|
<div>
|
||||||
<label>Username:</label>
|
<label>Username:</label>
|
||||||
{{with .Form.FieldErrors.username}}
|
{{with .Form.FieldErrors.username}}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<div>
|
<div>
|
||||||
{{if .IsAuthenticated}}
|
{{if .IsAuthenticated}}
|
||||||
<form action="/user/logout" method="POST">
|
<form action="/user/logout" method="POST">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
||||||
<button>Logout</button>
|
<button>Logout</button>
|
||||||
</form>
|
</form>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
Loading…
Reference in New Issue
Block a user