Reputation: 1
So, for the life of me I cannot figure out how to get gorilla's csrf to work when not injecting it straight into fields. It keeps talking about passing it through headers and cookies, but nothing I do seems to work... here's what I have for my go server:
`
package main
import (
"gorilla/mux"
"gorilla/csrf"
"net/http"
"log"
"encoding/json"
"http/template"
"time"
)
func showLoginPage(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
templates.ExecuteTemplate(w, "<template_here>", nil)
}
func doLogin(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
/**
builds resp
**/
w.Write(resp)
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/login", showLoginPage).Methods("GET")
r.HandleFunc("/login", doLogin).Methods("POST")
r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(http.Dir("./js"))))
r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir("./css"))))
srv := &http.Server{
Handler: csrf.Protect([]byte("very-secret-string"), csrf.Secure(false))(r),
Addr: "127.0.0.1:8000",
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
`
whereas, on my frontend I have this so that all requests get updated: `
var getCookie = function(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1);
if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
}
return "";
};
$.ajaxPrefilter(function( options ) {
options.beforeSend = function (xhr) {
xhr.setRequestHeader('X-CSRF-Token', getCookie('_gorilla_csrf'));
}
});
`
I know I have to be missing something, but I really just can't seem to grasp this at all. Any help would be very appreciated.
Upvotes: 0
Views: 2062
Reputation: 4791
It seems you're overwriting the gorilla created real CSRF token using this line. Gorilla is using session store to keep real CSRF tokens for validation.
w.Header().Set("Set-Cookie", "_gorilla_csrf="+csrf.Token(r))
Please do not touch _gorilla_csrf
this cookie.
Gorilla supports the CSRF via form field
and header
only. So pick your choice, their readme has required information you need (Form field, Header and Customizing field name & header name).
gorilla/csrf
checks CSRF token in this order:
gorilla/csrf inspects the HTTP headers (first) and form body (second) on subsequent POST/PUT/PATCH/DELETE/etc. requests for the token.
Upvotes: 1