I am using NoSurf for CSRF in my Golang code. This is from Trevor Sawler's Golang course, section 8.2. If anything, I decide to go with Bootstrap 5 instead the tutorial's Bootstrap 4. My code can be found here. To activate the web server, I use go run ./cmd/web/*.go
. So inside cmd\web\routes.go
, the following are available for the localhost:8080/search-availability
page:
mux.Get("/search-availability", handlers.Repo.Availability)
mux.Post("/search-availability", handlers.Repo.AvailabilityPost)
Inside pkg\handlers\handlers.go
, I have:
func (m *Repository) Availability(w http.ResponseWriter, r *http.Request) {
log.Println("Availability")
render.RenderTemplate(w, r, "search-availability.page.tmpl", &models.TemplateData{})
}
func (m *Repository) AvailabilityPost(w http.ResponseWriter, r *http.Request) {
log.Println("Before Write")
w.Write([]byte("Posted to search-availability"))
log.Println("After Write")
}
Inside pkg\render\render.go
, I have:
func AddDefaultData(td *models.TemplateData, r *http.Request) *models.TemplateData {
td.CsrfToken = nosurf.Token(r)
return td
}
Inside pkg\models\templatedata.go
, I have:
type TemplateData struct {
StringMap map[string]string
IntMap map[string]int
FloatMap map[string]float64
Data map[string]interface{}
CsrfToken string
Flash string
Error string
}
Inside templates\search-availability.page.tmpl
, I have on line 13:
<input type="text" name="csrf_token" value="{{.CsrfToken}}">
After choosing the start and end date from the localhost:8080/search-availability
page, clicking on the Search Availability
button always gets me a 400 Bad Request
as seen below.
From the terminal, I can see that the code never enters AvailabilityPost
:
2023/03/12 19:06:48 Hit the page
2023/03/12 19:06:48 Availability
2023/03/12 19:06:51 Hit the page
However if I disable nosurf
inside cmd\web\routes.go
like this:
func routes(app *config.AppConfig) http.Handler {
mux := chi.NewRouter()
mux.Use(middleware.Recoverer)
mux.Use(WriteToConsole)
// mux.Use(NoSurf)
mux.Use(SessionLoad)
...
mux.Get("/search-availability", handlers.Repo.Availability)
mux.Post("/search-availability", handlers.Repo.AvailabilityPost)
...
fileServer := http.FileServer(http.Dir("./static/"))
mux.Handle("/static/*", http.StripPrefix("/static", fileServer))
return mux
}
The browser shows a successful post:
Posted to search-availability
The terminal also confirms:
2023/03/12 19:19:46 Hit the page
2023/03/12 19:19:46 Availability
2023/03/12 19:19:48 Hit the page
2023/03/12 19:19:48 Before Write
2023/03/12 19:19:48 After Write
Could someone point out what I have done wrong? I am not getting a successful post as seen in the tutorial. The material is a bit dated, but I can't see how it be an issue.