I'm writing a go and react application.
I am trying to use gorilla / csrf as a CSRF countermeasure for SPA.
go and react are developed in completely independent domains.
go port8080 react port3000
I wrote the following code to set the csrf token.
func Route(app *App) *mux.Router {
r := mux.NewRouter()
csrfMiddleware := csrf.Protect([]byte("32-byte-long-auth-key"), csrf.Secure(false))
api := r.PathPrefix("/api").Subrouter()
api.Use(csrfMiddleware)
// user
api.HandleFunc("/users/{id:[0-9]+}", app.tokenVerifyMiddleWare(app.userGetHandler)).Methods("GET", "OPTIONS")
api.HandleFunc("/users", app.signupHandler).Methods("POST", "OPTIONS")
api.HandleFunc("/users/{id:[0-9]+}", app.userDeleteHandler).Methods("DELETE", "OPTIONS")
api.HandleFunc("/users/{id:[0-9]+}", app.userUpdateHandler).Methods("PUT", "OPTIONS")
// like
api.HandleFunc("/users/{id:[0-9]+}/likes", app.tokenVerifyMiddleWare(app.likeGetALLHandler)).Methods("GET", "OPTIONS")
api.HandleFunc("/users/{id:[0-9]+}/likes", app.tokenVerifyMiddleWare(app.likePostHandler)).Methods("POST", "OPTIONS")
api.HandleFunc("/users/{id:[0-9]+}/likes/{id:[0-9]+}", app.tokenVerifyMiddleWare(app.likeDeleteHandler)).Methods("DELETE", "OPTIONS")
// auth
api.HandleFunc("/login", app.loginHandler).Methods("POST", "OPTIONS")
api.HandleFunc("/logout", app.tokenVerifyMiddleWare(app.logoutHandler)).Methods("POST", "OPTIONS")
api.HandleFunc("/refresh_token", app.refreshTokenHandler).Methods("POST", "OPTIONS")
}
Route is called below.
func run() error {
app := controllers.NewApp(models)
r := controllers.Route(app)
http.Handle("/", r)
fmt.Printf("connected port :%d|\n", 8080)
return http.ListenAndServe(fmt.Sprintf(":%d", 8080), nil)
}
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
and set header in middleware
w.Header().Set("X-CSRF-Token", csrf.Token(r))
What Should I do by React then?
I tried this code from https://github.com/gorilla/csrf#javascript-applications
// You can alternatively parse the response header for the X-CSRF-Token, and
// store that instead, if you followed the steps above to write the token to a
// response header.
let csrfToken = document.getElementsByName("gorilla.csrf.Token")[0].value
// via https://github.com/axios/axios#creating-an-instance
const instance = axios.create({
baseURL: "https://example.com/api/",
timeout: 1000,
headers: { "X-CSRF-Token": csrfToken }
})
// Now, any HTTP request you make will include the csrfToken from the page,
// provided you update the csrfToken variable for each render.
try {
let resp = await instance.post(endpoint, formData)
// Do something with resp
} catch (err) {
// Handle the exception
}
and then
console.log(csrfToken) => undefined