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

2 回复

尝试将主机名设置为 "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})
})

主要问题:

  1. 跨域请求需要正确配置CORS
  2. withCredentials: true 必须在前端请求中设置
  3. Cookie的SameSite和Secure属性需要根据环境正确配置
  4. 本地开发时,React和Go服务需要使用不同的端口,需要明确指定Domain
回到顶部