可行但需禁用html渲染、显式配置cors、jwt的exp须为int64秒级时间戳、authorization头格式严格、文件上传需校验err并生成唯一文件名。

小程序后台用 Gin 是可行的,但必须绕开它默认的 HTML 渲染逻辑、禁用模板自动加载,并专注 JSON 接口设计——否则你会在 CORS、Content-Type、预检请求上反复踩坑。
为什么 gin.Default() 不能直接用于小程序后端
gin.Default() 默认启用了 Logger 和 Recovery 中间件,看似省事,但它还会悄悄加载 HTMLRender(哪怕你没调用 LoadHTMLGlob),导致某些错误响应返回 text/html 而非 application/json,微信开发者工具里看到 500 却收不到 error 字段;更隐蔽的是,它默认不设置 Access-Control-Allow-Origin,而小程序要求后端显式允许 https://servicewechat.com 或具体域名。
- 用
gin.New()替代gin.Default(),自己注册需要的中间件 - 显式禁用模板引擎:
engine.Delims("", "")+ 不调用任何LoadHTML*方法 - 加一个跨域中间件,至少允许
Origin为微信域名或 localhost(开发期)
小程序登录态对接 JWT 的三个硬性条件
微信小程序用 code2Session 换取 openid 后,后端需生成 JWT 并返回给前端存储。但 gin-jwt 或手写中间件若不满足这三点,后续所有接口都会 401:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
-
exp字段必须是 int64 秒级 Unix 时间戳,不是字符串、不是毫秒:jwt.MapClaims{"exp": time.Now().Add(24 * time.Hour).Unix()} - Header 必须是
Authorization: Bearer xxx,前后不能有多余空格;微信小程序调用时得手动拼:headers: { Authorization: 'Bearer ' + token } - 中间件必须全局注册:
router.Use(authMiddleware.MiddlewareFunc()),不能只挂到/api/v1group 下——否则未登录用户能直击/health或静态资源路由
接收小程序上传文件的注意事项
小程序用 wx.uploadFile 发送 multipart/form-data,但默认不带 filename,c.FormFile("file") 可能返回 nil, nil 而不是报错,导致静默失败。
- 务必检查
err:file, err := c.FormFile("file"); if err != nil { ... } - 不要依赖
file.Filename,小程序传过来常为空,改用服务端生成唯一名(如uuid.New().String() + filepath.Ext(file.Filename)) - 限制大小:在中间件里用
c.Request.ParseMultipartForm(32 设上限(如 32MB),超限直接 400,避免 OOM
调试时 curl 和微信开发者工具行为不一致怎么办
常见现象:curl 测试一切正常,但小程序里 request fail,控制台显示 net::ERR_CONNECTION_REFUSED 或 request:fail ssl hand shake error。
- 确认服务监听的是
0.0.0.0:8080,不是127.0.0.1:8080(iOS 模拟器、真机无法访问 localhost) - 本地开发务必用 HTTPS:微信强制要求后端域名备案且启用 TLS;可用
mkcert生成本地可信证书,启动时用engine.RunTLS(":443", "cert.pem", "key.pem") - 关掉防火墙或临时放行端口;Windows 用户注意 Hyper-V / WSL2 网络隔离可能拦截 443
最易被忽略的一点:小程序的 request API 默认不携带 cookie,所以别指望靠 session 存登录态;JWT 必须存在 header 里,且每次调用都要传——漏一次,就退回到未登录状态。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










