beego 中接收 github webhook 需显式启用 copyrequestbody = true,用 json.unmarshal 解析 json body,校验 x-hub-signature-256 签名,确保工作目录正确、权限充足,并通过 systemd/supervisord 守护进程,路由与 payload 过滤保障安全。

Beego 里怎么接收 GitHub 的 webhook 请求
Beego 默认不自动解析 application/json 类型的 POST body,而 GitHub 发送的 webhook 是标准 JSON 格式,直接读 this.Ctx.Input.RequestBody 会是空的或乱码。
必须显式启用 JSON 解析,且注意 GitHub 会在请求头里带 X-Hub-Signature-256(或旧版 X-Hub-Signature),用于校验 secret —— 这步漏掉等于裸奔。
- 在
main.go初始化时加:web.BConfig.CopyRequestBody = true - 控制器中用
json.Unmarshal(this.Ctx.Input.RequestBody, &payload)解析,别用this.GetString()或表单方式 - 校验签名需用
hmac.New(sha256.New, []byte(secret)),再比对 Base64 编码后的结果,GitHub 的签名是sha256=xxx格式,要截掉前缀
如何让 Beego 服务稳定监听 webhook 端口不退出
本地 bee run 能跑通,但部署后常因进程意外退出、端口被占、无守护导致 webhook 失效。Beego 本身不带进程管理,得靠外部手段补足。
- 不要直接
./myapp启动:没日志、无重启、OOM 时静默挂掉 - 推荐用
supervisord或systemd管理,比如 systemd unit 文件里写Restart=always和StandardOutput=append:/var/log/mywebhook.log - Beego 默认监听
0.0.0.0:8080,生产环境务必改用非特权端口(如 8081),再由 Nginx 反代并加 HTTPS,否则 GitHub 会拒绝回调(它要求 endpoint 必须是 HTTPS 或 localhost)
收到 webhook 后执行 git pull 为什么总失败
常见现象是日志里报 fatal: not a git repository 或 Permission denied (publickey),本质是权限和工作目录错位。
- Beego 进程运行用户(如
www-data)必须对目标项目目录有完整读写权,chown -R www-data:www-data /path/to/site -
git pull前必须cd到项目根目录,不能依赖相对路径;建议在代码里用os.Chdir("/path/to/site")显式切换 - 免密拉取要用 deploy key:生成
ssh-keygen -t ed25519 -C "webhook@server",把公钥加到 GitHub 仓库的 Deploy keys,私钥放在服务器上并chmod 600 - 别在 Beego 控制器里直接
exec.Command("git", "pull")—— 没环境变量,SSH agent 不生效;应封装成独立 shell 脚本,用su -s /bin/bash -c "/path/to/deploy.sh" www-data调用
Beego webhook 路由和分支过滤怎么写才安全
GitHub 一个仓库可能触发多个事件(push、pull_request、star),还可能来自不同分支。不做过滤,master 没动却去 reload 服务,或者测试分支误触发上线,就出大事了。
- 路由别用泛匹配:
web.Router("/webhook", &controllers.HookController{}, "post:Index")就够,别写:id或正则捕获 - 解析 payload 后立刻检查:
if payload.Repository.FullName != "owner/repo" || payload.Ref != "refs/heads/master" { return } - 区分事件类型:
if payload.Action == "closed" && payload.PullRequest.Merged { /* merge to master */ },避免 PR 打开就构建 - 加个简单限流:用
sync.Map记录 IP + 时间戳,5 秒内同 IP 重复请求直接this.Abort("429"),防恶意重放
Beego 做 webhook 服务不难,难的是边界情况——签名校验错一位、git 用户权限少一个 x、shell 脚本里忘了 set -e。这些地方不出问题时一切正常,一出就是线上停服。











