added CSRF
This commit is contained in:
parent
a06e8db2ff
commit
5c7d92f4f3
10 changed files with 42 additions and 6 deletions
|
@ -14,6 +14,7 @@ func main() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
h := web.NewHandler(store)
|
csrfKey := []byte("dmwij82jda92jf9a202na#d2.e3i!824")
|
||||||
|
h := web.NewHandler(store, csrfKey)
|
||||||
http.ListenAndServe(":3000", h)
|
http.ListenAndServe(":3000", h)
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -5,6 +5,7 @@ go 1.16
|
||||||
require (
|
require (
|
||||||
github.com/go-chi/chi v1.5.4 // indirect
|
github.com/go-chi/chi v1.5.4 // indirect
|
||||||
github.com/google/uuid v1.3.0 // direct
|
github.com/google/uuid v1.3.0 // direct
|
||||||
|
github.com/gorilla/csrf v1.7.1 // indirect
|
||||||
github.com/jmoiron/sqlx v1.3.4 // indirect
|
github.com/jmoiron/sqlx v1.3.4 // indirect
|
||||||
github.com/lib/pq v1.10.2 // indirect
|
github.com/lib/pq v1.10.2 // indirect
|
||||||
)
|
)
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -9,6 +9,10 @@ github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIu
|
||||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/gorilla/csrf v1.7.1 h1:Ir3o2c1/Uzj6FBxMlAUB6SivgVMy1ONXwYgXn+/aHPE=
|
||||||
|
github.com/gorilla/csrf v1.7.1/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
|
||||||
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
|
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
|
||||||
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
|
@ -22,5 +26,7 @@ github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/ogier/pflag v0.0.1 h1:RW6JSWSu/RkSatfcLtogGfFgpim5p7ARQ10ECk5O750=
|
github.com/ogier/pflag v0.0.1 h1:RW6JSWSu/RkSatfcLtogGfFgpim5p7ARQ10ECk5O750=
|
||||||
github.com/ogier/pflag v0.0.1/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g=
|
github.com/ogier/pflag v0.0.1/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
<div class="card mb-4">
|
<div class="card mb-4">
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<form action="/threads/{{.Thread.ID}}/{{.Post.ID}}" method="POST">
|
<form action="/threads/{{.Thread.ID}}/{{.Post.ID}}" method="POST">
|
||||||
|
{{.CSRF}}
|
||||||
<textarea name="content" class="form-control border-0 border-bottom-1 p-3"
|
<textarea name="content" class="form-control border-0 border-bottom-1 p-3"
|
||||||
placeholder="What are your thoughts?" rows="4"></textarea>
|
placeholder="What are your thoughts?" rows="4"></textarea>
|
||||||
<div class="border-top p-1">
|
<div class="border-top p-1">
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
{{define "content"}}
|
{{define "content"}}
|
||||||
<form action=/threads/{{.Thread.ID}} method="POST">
|
<form action=/threads/{{.Thread.ID}} method="POST">
|
||||||
|
{{.CSRF}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Title</label>
|
<label>Title</label>
|
||||||
<input name="title" type="text" class="form-control" placeholder="Give your post a great title">
|
<input name="title" type="text" class="form-control" placeholder="Give your post a great title">
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<form action=/threads/{{.Thread.ID}}/delete method="POST">
|
<form action=/threads/{{.Thread.ID}}/delete method="POST">
|
||||||
|
{{.CSRF}}
|
||||||
<button type="submit" class="text-danger btn-sm btn btn-link">Delete this thread</button>
|
<button type="submit" class="text-danger btn-sm btn btn-link">Delete this thread</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
{{define "content"}}
|
{{define "content"}}
|
||||||
<form action="/threads" method="POST">
|
<form action="/threads" method="POST">
|
||||||
|
{{.CSRF}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Title</label>
|
<label>Title</label>
|
||||||
<input name="title" type="text" class="form-control" placeholder="Give your thread a great title">
|
<input name="title" type="text" class="form-control" placeholder="Give your thread a great title">
|
||||||
|
|
|
@ -7,9 +7,10 @@ import (
|
||||||
"git.snrd.de/Spaenny/goddit"
|
"git.snrd.de/Spaenny/goddit"
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/go-chi/chi/middleware"
|
"github.com/go-chi/chi/middleware"
|
||||||
|
"github.com/gorilla/csrf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewHandler(store goddit.Store) *Handler {
|
func NewHandler(store goddit.Store, csrfKey []byte) *Handler {
|
||||||
h := &Handler{
|
h := &Handler{
|
||||||
Mux: chi.NewMux(),
|
Mux: chi.NewMux(),
|
||||||
store: store,
|
store: store,
|
||||||
|
@ -20,6 +21,7 @@ func NewHandler(store goddit.Store) *Handler {
|
||||||
comments := CommentHandler{store: store}
|
comments := CommentHandler{store: store}
|
||||||
|
|
||||||
h.Use(middleware.Logger)
|
h.Use(middleware.Logger)
|
||||||
|
h.Use(csrf.Protect(csrfKey, csrf.Secure(false)))
|
||||||
|
|
||||||
h.Get("/", h.Home())
|
h.Get("/", h.Home())
|
||||||
h.Route("/threads", func(r chi.Router) {
|
h.Route("/threads", func(r chi.Router) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"git.snrd.de/Spaenny/goddit"
|
"git.snrd.de/Spaenny/goddit"
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/gorilla/csrf"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PostHandler struct {
|
type PostHandler struct {
|
||||||
|
@ -15,6 +16,7 @@ type PostHandler struct {
|
||||||
|
|
||||||
func (h *PostHandler) Create() http.HandlerFunc {
|
func (h *PostHandler) Create() http.HandlerFunc {
|
||||||
type data struct {
|
type data struct {
|
||||||
|
CSRF template.HTML
|
||||||
Thread goddit.Thread
|
Thread goddit.Thread
|
||||||
}
|
}
|
||||||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/post_create.html"))
|
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/post_create.html"))
|
||||||
|
@ -33,12 +35,16 @@ func (h *PostHandler) Create() http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl.Execute(w, data{Thread: t})
|
tmpl.Execute(w, data{
|
||||||
|
CSRF: csrf.TemplateField(r),
|
||||||
|
Thread: t,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *PostHandler) Show() http.HandlerFunc {
|
func (h *PostHandler) Show() http.HandlerFunc {
|
||||||
type data struct {
|
type data struct {
|
||||||
|
CSRF template.HTML
|
||||||
Thread goddit.Thread
|
Thread goddit.Thread
|
||||||
Post goddit.Post
|
Post goddit.Post
|
||||||
Comments []goddit.Comment
|
Comments []goddit.Comment
|
||||||
|
@ -78,7 +84,12 @@ func (h *PostHandler) Show() http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpl.Execute(w, data{Thread: t, Post: p, Comments: cc})
|
tmpl.Execute(w, data{
|
||||||
|
CSRF: csrf.TemplateField(r),
|
||||||
|
Thread: t,
|
||||||
|
Post: p,
|
||||||
|
Comments: cc,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"git.snrd.de/Spaenny/goddit"
|
"git.snrd.de/Spaenny/goddit"
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/gorilla/csrf"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ThreadHandler struct {
|
type ThreadHandler struct {
|
||||||
|
@ -31,14 +32,20 @@ func (h *ThreadHandler) List() http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ThreadHandler) Create() http.HandlerFunc {
|
func (h *ThreadHandler) Create() http.HandlerFunc {
|
||||||
|
type data struct {
|
||||||
|
CSRF template.HTML
|
||||||
|
}
|
||||||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/thread_create.html"))
|
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/thread_create.html"))
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
tmpl.Execute(w, nil)
|
tmpl.Execute(w, data{
|
||||||
|
CSRF: csrf.TemplateField(r),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ThreadHandler) Show() http.HandlerFunc {
|
func (h *ThreadHandler) Show() http.HandlerFunc {
|
||||||
type data struct {
|
type data struct {
|
||||||
|
CSRF template.HTML
|
||||||
Thread goddit.Thread
|
Thread goddit.Thread
|
||||||
Posts []goddit.Post
|
Posts []goddit.Post
|
||||||
}
|
}
|
||||||
|
@ -61,7 +68,11 @@ func (h *ThreadHandler) Show() http.HandlerFunc {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tmpl.Execute(w, data{Thread: t, Posts: pp})
|
tmpl.Execute(w, data{
|
||||||
|
CSRF: csrf.TemplateField(r),
|
||||||
|
Thread: t,
|
||||||
|
Posts: pp,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue