Gin后端通过FuncName字段路由Server Action而非URL路径,前端漏传或拼错该字段会导致404;rsa.SignPKCS1v15要求传入已计算的哈希摘要字节,不可直接传原文。

前端调用时必须传 FuncName 和 Params
React Server Action 发起请求时,Gin 后端靠 FuncName 字段路由到具体业务逻辑,不是靠 URL 路径区分函数。如果前端漏传或拼错这个字段,后端会直接返回 404 并提示“未找到对应的 Server Action 函数”。
常见错误现象:POST /api/server-action 404,但路由明明注册了;查日志发现 req.FuncName 是空字符串或不存在的值。
实操建议:
• 前端确保每个 Server Action 的 useActionState 或 form action 对应的函数名,与后端 switch req.FuncName 中的 case 值完全一致(大小写敏感)
• 后端在 c.ShouldBindJSON(&req) 后加一行日志:log.Printf("RSA request: %+v", req),快速定位字段缺失问题
• 不要用 req.Params 直接当结构体反序列化——它只是字符串,需手动 json.Unmarshal([]byte(req.Params), &targetStruct)
rsa.SignPKCS1v15 要求哈希摘要已计算好
Go 标准库的 rsa.SignPKCS1v15 不接受原始数据,只接受已哈希后的字节切片(如 sha256.Sum256 的 [:])。如果直接传原文,会 panic 或签名失败。
典型错误:用 rsa.SignPKCS1v15(r, privKey, crypto.SHA256, []byte("raw data")) —— 这里 "raw data" 没经过 SHA256 哈希,函数内部会尝试哈希,但参数类型不匹配导致崩溃。
正确做法:
• 先算摘要:h := sha256.New(); h.Write(data); digest := h.Sum(nil)
• 再签名:signature, err := rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA256, digest)
• 验证时也必须用同样哈希算法和同样原始数据重算摘要,否则 rsa.VerifyPKCS1v15 返回 x509.ErrSignatureInvalid
Gin 中间件拦截 HTTP 请求强制跳转 HTTPS 有陷阱
很多教程抄的中间件只检查 X-Forwarded-Proto,但在 Nginx 反向代理没配 proxy_set_header X-Forwarded-Proto $scheme; 时,这个 header 永远为空,导致跳转失效或无限重定向。
更可靠的做法是结合监听端口判断:
• 若服务监听 :80,且请求来自非 TLS 连接(c.Request.TLS == nil),才做 301 跳转
• 同时确保 r.RunTLS(":443", "cert.pem", "key.pem") 单独启动 HTTPS 服务,不要混用 Run 和 RunTLS
• 自签名证书调试阶段,客户端(如 curl、Postman)需加 --insecure,浏览器会报 NET::ERR_CERT_AUTHORITY_INVALID,这是预期行为,不影响签名逻辑本身
私钥加载失败常因 PEM 格式换行符或权限问题
os.Open 读取私钥文件后,pem.Decode 失败的两个高频原因:
• 文件末尾多了 Windows 风格的 \r\n,导致 block.Bytes 解析失败,报 x509: failed to parse key
• 私钥文件权限太宽松(如 0644),Go 的 crypto/x509 包在某些系统上会拒绝加载,报 crypto/tls: private key file has group or world access
解决方法:
• 用 strings.TrimSpace(string(buf)) 清理换行符再传给 pem.Decode
• 私钥文件创建后立即执行 chmod 0600 server.key(Linux/macOS)或用 PowerShell icacls server.key /inheritance:r /grant:r "$env:USERNAME:(R)"(Windows)
• 不要硬编码路径,用 filepath.Join("config", "server.key") 配合相对路径管理


















