英文:
golang gin get cookie json
问题
我使用的是gin@v1.9.0版本。
尝试从请求中获取cookie。
cookie示例:
key={"ckey": "cvalue"}
代码:
token, err := c.Request.Cookie("key")
返回错误:
http: named cookie not present
但是如果没有花括号,就可以正常工作。
cookie示例:
key=cvalue
接收到的结果是:
token = "key=cvalue"
英文:
I use gin@v1.9.0
Trying to get cookie from request
Cookie example:
key={"ckey": "cvalue"}
code:
token, err := c.Request.Cookie("key")
Returns error
http: named cookie not present
But without curly braces, works fine
Cookie example:
key=cvalue
receive
token = "key=cvalue"
答案1
得分: 1
问题出现是因为 cookie 值的格式问题。
让我们看一下来自 net/http 的这些代码:
// Strip the quotes, if present.
if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
raw = raw[1 : len(raw)-1]
}
这个语句用于从字符串的开头和结尾去除 "
。但是无法移除 {"ckey": "cvalue"}
中的引号。
然后它调用另一个函数,这个函数是一个循环,遍历每个字符并检查字符是否是有效的字节。
for i := 0; i < len(raw); i++ {
if !validCookieValueByte(raw[i]) {
return "", false
}
}
validCookieValueByte 的实现如下:
func validCookieValueByte(b byte) bool {
return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'
}
在这里检查失败,因为 {"ckey": "cvalue"}
中有一个 "
。
让我们用一个示例代码来检查:
func main() {
router := gin.Default()
router.GET("/get-cookie", func(c *gin.Context) {
cookie, err := c.Request.Cookie("key")
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
c.String(http.StatusOK, fmt.Sprintf("token = key=%v", cookie.Value))
})
router.Run(":8080")
}
这个会失败:
curl --request GET \
--url http://localhost:8080/get-cookie \
--cookie key='{"ckey": "cvalue"}'
但这个会成功:
curl --request GET \
--url http://localhost:8080/get-cookie \
--cookie key='{ckey: cvalue}'
我们可以使用 http.Cookie 将 cookie 设置为 JSON 格式:
val := `{"ckey": "cvalue"}`
cookie := &http.Cookie{
Name: "key",
Value: val,
}
http.SetCookie(c.Writer, cookie)
在保存值之前,SetCookie 会移除 "
。
英文:
The issue is happening because of the cookie value format.
Let's look at these codes from net/http
// Strip the quotes, if present.
if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
raw = raw[1 : len(raw)-1]
}
this statement is used to strip the "
from the beginning and the end of the string.
{"ckey": "cvalue"}
the quotes from this string cannot be removed.
And then it call another function which is a loop that iterates through each characters and checks the character is a valid byte.
for i := 0; i < len(raw); i++ {
if !validCookieValueByte(raw[i]) {
return "", false
}
}
validCookieValueByte implementation
func validCookieValueByte(b byte) bool {
return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'
}
and the check is failing at here. Because we have a "
in {"ckey": "cvalue"}
Let's check with a sample code
func main() {
router := gin.Default()
router.GET("/get-cookie", func(c *gin.Context) {
cookie, err := c.Request.Cookie("key")
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
c.String(http.StatusOK, fmt.Sprintf("token = key=%v", cookie.Value))
})
router.Run(":8080")
}
This will fail
curl --request GET \
--url http://localhost:8080/get-cookie \
--cookie key='{"ckey": "cvalue"}'
but this will succeed
curl --request GET \
--url http://localhost:8080/get-cookie \
--cookie key='{ckey: cvalue}'
We can use http.Cookie to set the cookie as json
val := `{"ckey": "cvalue"}`
cookie := &http.Cookie{
Name: "key",
Value: val,
}
http.SetCookie(c.Writer, cookie)
SetCookie will remove the "
before saving the value.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论