英文:
CORS on golang server & javascript fetch frontend
问题
我有一个类似以下代码的golang HTTP服务器:
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
log.Println("New incoming request")
// 验证身份
if u, p, ok := r.BasicAuth(); ok {
log.Println("Success")
return
}
log.Println("Failed")
})
我从一个部署在端口3000上的JS前端(一个React应用)调用这个HTTP端点,使用以下代码:
fetch('http://localhost:8080/login', {
method: 'post',
headers: {
'Authorization': 'Basic ' + btoa(authHeader),
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*'
},
body: 'A=1&B=2'
})
.then(function (response) {
console.log("Authentication Success")
})
.catch(function (err) {
console.log("Authentication fail", err)
});
上述代码在以下日志中失败。
服务器端日志:
New incoming request
Failed
浏览器开发工具日志:
Fetch API cannot load http://localhost:8080/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
有人可以帮助解决身份验证问题吗?我不确定是否在服务器端遗漏了与CORS相关的内容,或者在客户端进行了错误的身份验证。谢谢。
英文:
I have a golang HTTP server with code like:
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
log.Println("New incoming request")
// Authenticate
if u, p, ok := r.BasicAuth(); ok {
log.Println("Success")
return
}
log.Println("Failed")
I call this HTTP endpoint from a JS frontend, a react app deployed on port 3000, using code:
fetch('http://localhost:8080/login', {
method: 'post',
headers: {
'Authorization': 'Basic ' + btoa(authHeader),
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*'
},
body: 'A=1&B=2'
})
.then(function (response) {
console.log("Authentication Success")
})
.catch(function (err) {
console.log("Authentication fail", err)
});
The above code fails with the following logs.
On the server side:
New incoming request
Failed
On the browser, in the developer tools logs:
Fetch API cannot load http://localhost:8080/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Can someone help fix the authentication problem ? I am not sure if I am missing something related to CORS on the server side or doing bad authentication on the client side. Any help ? Thanks.
答案1
得分: 4
Access-Control-Allow-Origin: *
必须由服务器发送,而不是由客户端发送。假设您正在使用标准的 net/http
处理函数,可以尝试以下代码:
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
if r.Method == "OPTIONS" {
w.Header().Set("Access-Control-Allow-Headers", "Authorization") // 如果需要,您可以在此处添加更多标头
} else {
// 在这里编写您的代码
}
}
请注意,这是Go语言的示例代码,用于在服务器端设置 Access-Control-Allow-Origin
标头。
英文:
The Access-Control-Allow-Origin: *
has to be sent from the server, not by the client. Assuming you are in a standard net/http
handler function, try this code:
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
if (r.Method == "OPTIONS") {
w.Header().Set("Access-Control-Allow-Headers", "Authorization") // You can add more headers here if needed
} else {
// Your code goes here
}
}
答案2
得分: 0
首先,在你的处理程序中需要使用模式(schema):
w.Header().Set("Access-Control-Allow-Origin", "*")
if r.Method == "OPTIONS" {
w.Header().Set("Access-Control-Allow-Headers", "Authorization") // 如果需要,你可以在这里添加更多的头部信息
} else {
// 在这里编写你的代码
}
但在此之前,你需要在主函数中指定 "OPTIONS":
router.HandleFunc("/your_route/", your_method).Methods("POST", "OPTIONS")
这是因为你的浏览器会发送两个请求 - 第一个是检查是否能够使用某些头部信息(例如 Authorization),然后才会发送数据。
英文:
First - you need to use schema in your handler:
w.Header().Set("Access-Control-Allow-Origin", "*")
if (r.Method == "OPTIONS") {
w.Header().Set("Access-Control-Allow-Headers", "Authorization") // You can add more headers here if needed
} else {
// Your code goes here
}
But before it you need to specify in main "OPTIONS":
router.HandleFunc("/your_route/", your_method).Methods("POST", "OPTIONS")
It's because your browser doing 2 request - first to check ability to use some headers (Authorization for example) and next step is posting data
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论