我正在编写一个 go and react 应用程序。
我正在尝试使用 gorilla / csrf 作为 SPA 的 CSRF 对策。
go 和 react 是在完全独立的领域开发的。
去 port8080 反应 port3000
我编写了以下代码来设置 csrf 令牌。
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")
}
路线在下面被调用。
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)
}
}
并在中间件中设置标题
w.Header().Set("X-CSRF-Token", csrf.Token(r))
那我应该用 React 做什么?
我从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
}
接着
console.log(csrfToken) => undefined