Golang中Gin框架的securecookie报错:base64解码失败

Golang中Gin框架的securecookie报错:base64解码失败 我正在尝试设置和读取一个安全的服务器端Cookie。看不出我哪里做错了。解码时出现错误 securecookie: base64 decode failed - caused by: illegal base64 data at input byte 203。 也许是因为在这个位置有一个百分号。

我创建了一个非常简单的应用程序来演示我的问题:

https://github.com/omsec/cookietest/blob/main/controllers/authentication.go 中,我尝试在 “Login” 函数中写入:

tokens := map[string]string{
		"access_token":  "test_at",
		"refresh_token": "test_rt"}

然后在 “GetSomething” 处理函数中读取它。

实际的Cookie操作封装在这里:https://github.com/omsec/cookietest/blob/main/helpers/cookie.go

package helpers

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/securecookie"
)

// SetCookie writes a cookie
func SetCookie(c *gin.Context, name string, value interface{}) error {

	var sck = securecookie.New([]byte("thisIsExactly32BytesLongYeah1234"), []byte("thisIsExactly32BytesLongYeah1234"))

	encoded, err := sck.Encode(name, value)
	if err != nil {
		return err
	}

错误发生在 “GetCookie” 函数的第48行。

我这样做错了吗?


更多关于Golang中Gin框架的securecookie报错:base64解码失败的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

嗯,我不是说这是个bug,毕竟我不是专家,只是个Go语言的初学者……

我切换到了这个实现,它按预期工作了:

GitHub chmike/securecookie

头像

chmike/securecookie

快速、安全、高效的加密Cookie编码器/解码器 - chmike/securecookie

更多关于Golang中Gin框架的securecookie报错:base64解码失败的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题出在securecookie的密钥长度上。securecookie要求认证密钥必须是32或64字节,加密密钥必须是16、24或32字节。你使用了相同的32字节字符串作为两个密钥,但securecookie对这两个密钥有不同的要求。

以下是修复后的代码:

package helpers

import (
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/gorilla/securecookie"
)

var sck = securecookie.New(
    []byte("thisIsExactly32BytesLongYeah1234"), // 32字节认证密钥
    []byte("thisIs16BytesLong!"),               // 16字节加密密钥
)

// SetCookie writes a cookie
func SetCookie(c *gin.Context, name string, value interface{}) error {
    encoded, err := sck.Encode(name, value)
    if err != nil {
        return err
    }
    
    cookie := &http.Cookie{
        Name:     name,
        Value:    encoded,
        Path:     "/",
        Secure:   true,
        HttpOnly: true,
        SameSite: http.SameSiteLaxMode,
    }
    
    http.SetCookie(c.Writer, cookie)
    return nil
}

// GetCookie reads a cookie
func GetCookie(c *gin.Context, name string, dst interface{}) error {
    cookie, err := c.Request.Cookie(name)
    if err != nil {
        return err
    }
    
    return sck.Decode(name, cookie.Value, dst)
}

在main.go中初始化全局变量:

package main

import (
    "github.com/gin-gonic/gin"
    "your-project/helpers"
)

func main() {
    r := gin.Default()
    
    // 使用修复后的cookie助手
    r.GET("/login", func(c *gin.Context) {
        tokens := map[string]string{
            "access_token":  "test_at",
            "refresh_token": "test_rt",
        }
        
        if err := helpers.SetCookie(c, "session", tokens); err != nil {
            c.JSON(500, gin.H{"error": err.Error()})
            return
        }
        
        c.JSON(200, gin.H{"status": "cookie set"})
    })
    
    r.GET("/data", func(c *gin.Context) {
        var tokens map[string]string
        if err := helpers.GetCookie(c, "session", &tokens); err != nil {
            c.JSON(400, gin.H{"error": err.Error()})
            return
        }
        
        c.JSON(200, gin.H{"tokens": tokens})
    })
    
    r.Run(":8080")
}

关键修改:

  1. 使用不同的密钥:32字节用于认证,16字节用于加密
  2. 将securecookie实例声明为全局变量,避免每次请求都创建新实例
  3. 确保cookie设置正确的属性(Secure、HttpOnly等)

这样可以解决base64解码失败的问题,因为securecookie现在能正确编码和解码数据了。

回到顶部