'Golang CSRF issues with React
I'm creating a React application which talks to a backend written in Go. I have setup CSRF using the Gorilla library. The React code will first send a GET request to the csrfToken endpoint where it receives a token. This token is set in the header when sending the POST request.
func main() {
r := mux.NewRouter()
r.HandleFunc("/signup/post", SubmitSignupForm).Methods(http.MethodPost, http.MethodOptions)
r.HandleFunc("/csrfToken", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(csrf.Token(r)))
})
r.Use(csrf.Protect(
[]byte("fff"),
csrf.Path("/"),
csrf.Secure(false),
csrf.TrustedOrigins([]string{"http://localhost:3001/"}),
csrf.RequestHeader("TOKEN"),
))
c := cors.AllowAll()
http.ListenAndServe(":8000", c.Handler(r))
}
The React code looks like this:
import React from 'react';
import './App.css';
import useAxios from "axios-hooks";
function App() {
const [{response: csrfToken}] = useAxios<string>({url: "http://localhost:8000/csrfToken"})
const [{response}, doRequest] = useAxios<string>({
url: "http://localhost:8000/signup/post",
method: "POST"
}, {manual: true})
return (
<div className="App">
<header className="App-header">
<h1>hello</h1>
<h1>csrf: {csrfToken?.data}</h1>
<h1>Response: {response?.data}</h1>
<button onClick={e => {
doRequest({data: {key: "something"}, headers: {"TOKEN": csrfToken!.data}})
}}>click
</button>
</header>
</div>
);
}
export default App;
The thing that makes me the most confused is that I'm able to send a request with Postman to the /csrfTokenendpoint and use that value with the header.
However, when I do the same in the browser I get a 403 and responds Forbidden - CSRF token invalid.
Any ideas what I have done wrong?
Solution 1:[1]
I'm not familiar with axios-hooks, but don't you want to execute the csrf function in your react code and fetch the CSRF token like you are doing with doRequest()? There's no second property being destructured in the csrf like in doRequest().
If doing the csrf function without the second property executes the axios function, you may need an await or .then chain since it presumably returns a promise.
I think this question might be more React related than Go which looks fine to me.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | AlexMe |
