Golang中gin.setCookie与React.js配合使用的问题解决方案
Golang中gin.setCookie与React.js配合使用的问题解决方案 我正在使用Go和React开发自己的技术博客。 在管理员功能(如撰写或删除文章)的登录页面中,我希望检查用户(我自己)的密码,并在用户通过授权后设置一个Cookie。 此API的 参数:输入的密码 LoginData{}:包含两个字段 ‘Id’ 和 ‘Password’ 但是Cookie没有生效。 我认为从Go到React的响应发送是正常的,因为当我在管理员页面登录时,React会在控制台提示ID和密码是否正确。 但Cookie并未在浏览器中设置。 我在下面附上了Go和React的代码。
- go代码
eg.POST("/login/:param", func (c *gin.Context){
param := c.Param("param")
data := LoginData{}
if param == "pw" {
err = c.ShouldBindJSON(&data)
if err != nil {
fmt.Println("LOGIN DATA BINDING ERROR")
}
}
fmt.Println(data.Id)
fmt.Println(data.Password)
if data.Id != "myid"{
c.Writer.WriteHeader(http.StatusUnauthorized)
} else {
r, err := db.Query(`SELECT pw FROM login where id = "myid"`)
if err != nil {
fmt.Println("ID/PW DB INSERT ERROR")
}
var pwdata string
for r.Next() {
r.Scan(&pwdata)
}
err = bcrypt.CompareHashAndPassword([]byte(pwdata), []byte(data.Password))
if err != nil {
c.Writer.WriteHeader(http.StatusUnauthorized)
} else {
c.SetCookie("admin", "authorized",60*60,"/","",false,false)
}
}
})
- react代码
const loginHandler = () => {
const logindata = { id: id, pw: pw };
console.log(logindata);
axios
.post("http://localhost:8080/login/pw", logindata)
.then((response) => {
alert("You are logged in.");
console.log(response.headers["set-cookie"]);
setCookie(cookies.admin);
})
.catch((error) => {
alert("ID or PW doesn't match.");
});
};
提示信息“您已登录”和“ID或密码不匹配”工作正常。
有人知道这个问题的解决方案吗?
更多关于Golang中gin.setCookie与React.js配合使用的问题解决方案的实战教程也可以访问 https://www.itying.com/category-94-b0.html
尝试将主机名设置为 "localhost":
更改:
c.SetCookie("admin", "authorized",60*60,"/","",false,false)
为:
c.SetCookie("admin", "authorized",60*60,"/","localhost",false,false)
更多关于Golang中gin.setCookie与React.js配合使用的问题解决方案的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题在于跨域请求时Cookie的设置和传递。以下是解决方案:
1. 修改Go后端代码,添加CORS支持并调整Cookie设置:
import (
"github.com/gin-contrib/cors"
)
func main() {
r := gin.Default()
// 配置CORS
r.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:3000"}, // React开发服务器地址
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Type", "Accept"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true, // 允许凭证(包括Cookie)
MaxAge: 12 * 60 * 60,
}))
eg.POST("/login/:param", func(c *gin.Context) {
param := c.Param("param")
data := LoginData{}
if param == "pw" {
err = c.ShouldBindJSON(&data)
if err != nil {
fmt.Println("LOGIN DATA BINDING ERROR")
}
}
if data.Id != "myid" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
r, err := db.Query(`SELECT pw FROM login where id = "myid"`)
if err != nil {
fmt.Println("ID/PW DB INSERT ERROR")
}
var pwdata string
for r.Next() {
r.Scan(&pwdata)
}
err = bcrypt.CompareHashAndPassword([]byte(pwdata), []byte(data.Password))
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
} else {
// 修改Cookie设置,添加SameSite=None和Secure
c.SetCookie("admin", "authorized", 60*60, "/", "localhost", true, true)
c.JSON(http.StatusOK, gin.H{"status": "success"})
}
})
}
2. 修改React前端代码:
const loginHandler = () => {
const logindata = { id: id, pw: pw };
console.log(logindata);
axios.post("http://localhost:8080/login/pw", logindata, {
withCredentials: true, // 关键:允许发送和接收Cookie
headers: {
'Content-Type': 'application/json'
}
})
.then((response) => {
alert("You are logged in.");
console.log("Login successful");
// 检查Cookie是否设置成功
console.log(document.cookie);
})
.catch((error) => {
alert("ID or PW doesn't match.");
});
};
3. 如果需要手动处理Cookie,可以这样修改:
// Go端设置Cookie的替代方案
c.Writer.Header().Set("Set-Cookie", "admin=authorized; Max-Age=3600; Path=/; Domain=localhost; HttpOnly; Secure; SameSite=None")
c.JSON(http.StatusOK, gin.H{"status": "success"})
4. 添加Cookie验证端点:
// 验证Cookie的端点
eg.GET("/check-auth", func(c *gin.Context) {
cookie, err := c.Cookie("admin")
if err != nil || cookie != "authorized" {
c.JSON(http.StatusUnauthorized, gin.H{"authenticated": false})
return
}
c.JSON(http.StatusOK, gin.H{"authenticated": true})
})
主要问题:
- 跨域请求需要正确配置CORS
withCredentials: true必须在前端请求中设置- Cookie的SameSite和Secure属性需要根据环境正确配置
- 本地开发时,React和Go服务需要使用不同的端口,需要明确指定Domain

