localhost环境下Gin后端设置的Http Cookie无法在React前端浏览器存储
问题描述
登录请求成功后,通过Gin-Gonic后端使用ctx.SetCookie设置accesstoken和refreshtoken作为Http Cookie。使用Postman发起登录请求时Cookie可正常存储,但通过React.js前端在Firefox、Brave浏览器发起请求时,Cookie无法存入浏览器的/devtools/application/cookies中。已知新版浏览器可能忽略domain为localhost的设置,尝试过相关方案,但不想采用前端存储Token的方式,需在localhost测试环境下实现浏览器存储Cookie的目标。
相关代码
后端存储Cookie代码
ctx.SetCookie("accesstoken", token, int(AppConstant.TOKEN_COOKIE_EXPIRY), "/", "localhost", false, true) ctx.SetCookie("refreshtoken", refreshedToken, int(AppConstant.REFRESH_TOKEN_COOKIE_EXPIRY), "/", "localhost", false, true)
React前端登录请求代码
export async function AuthenticateUser (username,password) { const res=await fetch(API_URL+API_LOGIN_ENDPOINT,{ method:"POST", headers:{ 'Accept': 'application/json', "Content-Type":"application/json" }, mode:"cors", body:JSON.stringify({ "username":username, "password":password, }), }); return res.status===200 }
解决方案
调整后端Cookie的Domain参数
把Domain从"localhost"改为空字符串"",新版浏览器对localhost域名的Cookie规则严格,空字符串会让浏览器自动匹配当前请求的域名,避免因domain设置导致的Cookie被忽略。修改后的后端代码:ctx.SetCookie("accesstoken", token, int(AppConstant.TOKEN_COOKIE_EXPIRY), "/", "", false, true) ctx.SetCookie("refreshtoken", refreshedToken, int(AppConstant.REFRESH_TOKEN_COOKIE_EXPIRY), "/", "", false, true)前端请求添加
credentials: 'include'
跨域请求中,浏览器默认不会处理Cookie,必须显式设置credentials: 'include',才能让浏览器在请求中携带并保存Cookie。修改后的前端代码:export async function AuthenticateUser(username, password) { const res = await fetch(API_URL + API_LOGIN_ENDPOINT, { method: "POST", headers: { 'Accept': 'application/json', "Content-Type": "application/json" }, mode: "cors", credentials: 'include', // 新增该配置 body: JSON.stringify({ "username": username, "password": password, }), }); return res.status === 200 }确保后端CORS配置正确
Gin后端必须开启允许携带凭证的CORS设置,且AllowOrigins不能使用通配符*,需指定前端的具体地址(比如http://localhost:3000)。示例配置:import "github.com/gin-contrib/cors" func main() { r := gin.Default() corsConfig := cors.DefaultConfig() corsConfig.AllowOrigins = []string{"http://localhost:3000"} // 替换为你的前端端口 corsConfig.AllowCredentials = true corsConfig.AllowHeaders = []string{"Content-Type", "Accept"} r.Use(cors.New(corsConfig)) // 后续路由定义... }
内容的提问来源于stack exchange,提问作者PranayS
相关产品推荐
相关产品推荐

