Golang CSRF 问题与 React
Golang CSRF issues with React
我正在创建一个与用 Go 编写的后端对话的 React 应用程序。我已经使用 Gorilla 库设置了 CSRF。 React 代码将首先向接收令牌的 csrfToken
端点发送 GET 请求。此令牌在发送 POST 请求时在 header 中设置。
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))
}
React 代码如下所示:
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;
让我最困惑的是我能够使用 Postman 将请求发送到 /csrfToken
端点并将该值与 header.
一起使用
但是,当我在浏览器中执行相同操作时,我收到 403 并响应 Forbidden - CSRF token invalid
。
知道我做错了什么吗?
我不熟悉 axios-hooks,但是你不想在你的 React 代码中执行 csrf 函数并像使用 doRequest() 那样获取 CSRF 令牌吗?
没有第二个 属性 在 csrf 中被解构,就像在 doRequest() 中一样。
如果在没有第二个 属性 的情况下执行 csrf 函数会执行 axios 函数,您可能需要一个 await 或 .then 链,因为它可能 returns 一个承诺。
我认为这个问题可能比 Go 更适合 React,我觉得还不错。
我想通了。
我通过首先创建一个设置简单得多的虚拟项目来开始调试应用程序。在那里我成功地设置了一切。在了解这两个应用程序的差异时,我注意到 cookie 没有在不工作的应用程序中发送。
一段时间后,我了解到由于跨源,cookie 没有从浏览器发送到 API。所有这些都是 运行 本地的,我痛苦的错误是:
localhost != 127.0.0.1
我需要做的就是将所有使用 localhost 的地方更改为 127.0.0.1。由于浏览器认为两者来源不同,不会发送cookies...
我正在创建一个与用 Go 编写的后端对话的 React 应用程序。我已经使用 Gorilla 库设置了 CSRF。 React 代码将首先向接收令牌的 csrfToken
端点发送 GET 请求。此令牌在发送 POST 请求时在 header 中设置。
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))
}
React 代码如下所示:
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;
让我最困惑的是我能够使用 Postman 将请求发送到 /csrfToken
端点并将该值与 header.
但是,当我在浏览器中执行相同操作时,我收到 403 并响应 Forbidden - CSRF token invalid
。
知道我做错了什么吗?
我不熟悉 axios-hooks,但是你不想在你的 React 代码中执行 csrf 函数并像使用 doRequest() 那样获取 CSRF 令牌吗? 没有第二个 属性 在 csrf 中被解构,就像在 doRequest() 中一样。
如果在没有第二个 属性 的情况下执行 csrf 函数会执行 axios 函数,您可能需要一个 await 或 .then 链,因为它可能 returns 一个承诺。
我认为这个问题可能比 Go 更适合 React,我觉得还不错。
我想通了。
我通过首先创建一个设置简单得多的虚拟项目来开始调试应用程序。在那里我成功地设置了一切。在了解这两个应用程序的差异时,我注意到 cookie 没有在不工作的应用程序中发送。
一段时间后,我了解到由于跨源,cookie 没有从浏览器发送到 API。所有这些都是 运行 本地的,我痛苦的错误是:
localhost != 127.0.0.1
我需要做的就是将所有使用 localhost 的地方更改为 127.0.0.1。由于浏览器认为两者来源不同,不会发送cookies...