本文收录于 Github.com/niumoo/JavaNotes,Java 系列文档,数据结构与算法!

本文收录于网站:https://www.wdbyte.com/,我的公众号:程序猿阿朗

什么是 WebHook

WebHook 直译是网络钩子,可以把 WebHook 看做一种通知方式,只要发生关注的事件,就会发送通知到我们指定的 Web 服务。使用 WebHook 可以让我们在关注的事件发生时收到通知,而不是不断轮训 API 确认事件是否发生,

GitHub 允许我们配置 WebHook ,它允许我们配置某个仓库发生某个事件时,通知指定的外部服务。比如当指定仓库有提交代码时,GitHub 将向我们配置的 API 发送 POST 请求。以此可以实现相应的自动化操作,如持续集成 CI,请求代码审核,拉取新代码编译打包部署等。

发挥想象力,GitHub 的 WebHook 结合 GitHub Action 可以做很多事情,文末有具体例子。

这篇文章介绍 GitHub Web Hooks 的使用。

WebHook 配置

访问

访问 GitHub 仓库的 Webhooks 设置页面,打开仓库的 Settings 配置页面,点击 Webhook Tab 页。

也可以直接访问链接:https://github.com/用户/仓库/settings/hooks

配置

点击 Add webhook 按钮。

配置完成后,点击 Add webhook ,GitHub 会发送一个 POST 请求到配置的 web 服务用于验证是否正常。Web Hook 的事件会在请求头 X-GitHub-Event 中进行标识。

如上面说到的 ping ,会在请求头中进行标识:X-GitHub-Event: ping。’

一些说明:

  • Payload URL:此处填写你的 Web 服务地址,最好已经存在,这样 ping 事件才能正常响应。
  • Secret:安全密钥,用于对请求体进行哈希计算,用于验证是否为 GitHub 发送。后面部分会详细介绍绍。
  • SSL Verification:是否启用 SSL 验证,如果你的 Web 服务启用了 HTTPS,这里应该选择启用,也建议启用。
  • Just the push event:只订阅仓库 push 事件。

Ping 测试

点击 Add webhook 后发送一个请求到配置的 Web 服务,下面是一个真实的 ping 事件请求头信息。

Request URL: https://www.wdbyte.com/api/github/webhook
Request method: POST
Accept: */*
Content-Type: application/x-www-form-urlencoded
User-Agent: GitHub-Hookshot/eb2eabb
X-GitHub-Delivery: 10957020-e918-11ee-8a3e-e0754488dbc
X-GitHub-Event: ping
X-GitHub-Hook-ID: 468323437
X-GitHub-Hook-Installation-Target-ID: 33701056
X-GitHub-Hook-Installation-Target-Type: repository
X-Hub-Signature: sha1=1877dfa1d840bdd5583af33718cea722d825ed7
X-Hub-Signature-256: sha256=addaf81ed2f5795f06ba096b1c863b00188d3444367b5125d2036e17ca324e3

WebHook 消息验证

因为配置的 Web 服务 URL 是一个开放的 URL,任何人都可以访问,为了防止有人恶意构造 WebHook 消息请求,我们应该对收到的请求进行验证,判断是否为来自 GitHub Web Hook 的请求。

如何验证呢?是怎么样的一个流程呢?这时就要用到上面配置的 Secret 安全密钥了。

具体步骤如下:

  1. GitHub WebHook 使用 Secret 对 Post Body 内容进行哈希(HMAC 十六进制摘要)计算,得到一个哈希值,如 xxyyzz
  2. 将哈希值存入请求头 X-Hub-Signature-256 中,值以 sha256= 开头,如 sha256=xxyyzz
  3. Web 服务收到请求,使用相同的 Secret 对 Post Body 进行相同哈希算法计算。得到一个摘要。
  4. 取出 X-Hub-Signature-256 请求头的值进行比较,如果相同则表示请求来自 GitHub Web Hook。

下面是官方给出的 JavaScript 语言的验证实现:

let encoder = new TextEncoder();

async function verifySignature(secret, header, payload) {
let parts = header.split("=");
let sigHex = parts[1]; let algorithm = { name: "HMAC", hash: { name: 'SHA-256' } }; let keyBytes = encoder.encode(secret);
let extractable = false;
let key = await crypto.subtle.importKey(
"raw",
keyBytes,
algorithm,
extractable,
[ "sign", "verify" ],
); let sigBytes = hexToBytes(sigHex);
let dataBytes = encoder.encode(payload);
let equal = await crypto.subtle.verify(
algorithm.name,
key,
sigBytes,
dataBytes,
); return equal;
} function hexToBytes(hex) {
let len = hex.length / 2;
let bytes = new Uint8Array(len); let index = 0;
for (let i = 0; i < hex.length; i += 2) {
let c = hex.slice(i, i + 2);
let b = parseInt(c, 16);
bytes[index] = b;
index += 1;
} return bytes;
}

这种对内容进行摘要计算的验证方式其实很常见,在之前介绍过的 JWT 的原理中也有提到,感兴趣的可以查看:JSON Web Token 入门教程

注意:Secret 十分重要,应该妥善保存,防止泄漏。更不要存储到公开仓库之中。要天不知地不知,GitHub 知你知。

Java 验证 WebHook

网上有很多使用 Java 语言验证 GitHub WebHook 消息的代码实现,这里使用第三方依赖进行验证,省去哈希算法的编写。

引入依赖:

<dependency>
<groupId>am.ik.webhook</groupId>
<artifactId>webhook-verifier</artifactId>
<version>0.1.2</version>
</dependency>

消息验证:

private void verify(HttpServletRequest request, String body) {
HmacWebhookSigner webhookSigner = new HmacWebhookSigner("SHA256", secret);
WebhookVerifier verifier = new WebhookVerifier(webhookSigner, WebhookSigner.Encoder.HEX);
String signature = request.getHeader(WebhookHttpHeaders.X_HUB_SIGNATURE_256);
verifier.verify(body, signature);
}

验证通过没有任何返回,如果验证失败,会抛出 WebhookAuthenticationException 异常。

WebHook 最佳实践

遵循 WebHook 最佳实践可以提高其安全性和性能,下面是一些常用建议。

  1. 只订阅关注的事件,减少事件推送次数。
  2. 使用 HTTPS 提高安全性,HTTPS 已经是 Web 服务的标配。
  3. 配置白名单或验证策略,确保消息发送方可信,比如文中提到的秘钥哈希验证。
  4. 快速响应请求,很多 WebHook 推送对响应耗时有要求,比如 GitHub 是 10 秒,因此如果你的处理逻辑过于耗时,可以考虑异步处理,优先响应。

最后推荐一下必应壁纸网站https://bing.wdbyte.com/ ,这是一个使用 GitHub Action 自动抓取壁纸,然后通过 WebHook 自动构建部署的项目,近期会对其网站进行升级,增加收藏,不同尺寸壁纸下载功能,可以蹲下我的公众号

欢迎 Star:https://github.com/niumoo/bing-wallpaper

相关文章:如何使用 Github Actions 自动抓取每日必应壁纸?

本文收录于 Github.com/niumoo/JavaNotes,Java 系列文档,数据结构与算法!

本文收录于网站:https://www.wdbyte.com/,我的公众号:程序猿阿朗

GitHub WebHook 使用教程的更多相关文章

  1. 专为设计师而写的GitHub快速入门教程

    专为设计师而写的GitHub快速入门教程 来源: 伯乐在线 作者:Kevin Li     原文出处: Kevin Li 在互联网行业工作的想必都多多少少听说过GitHub的大名,除了是最大的开源项目 ...

  2. Github入门详情教程

    前言 之前我写了一篇文章<一篇文章了解Github和Git教程>还延伸了几篇阅读,对大部分小白很有用,那么我继续普及下Github页面及其概念. 定义 GitHub 是一个网站,一个面向开 ...

  3. 超详细!Github团队协作教程(Gitkraken版)

    超详细!Github团队协作教程(Gitkraken版) 一.前期工作 1. 在 Github 上创建 organization step1. 登录Github网站,点击右上角头像,选择 " ...

  4. 转载:GitHub 新手详细教程

    GitHub 新手详细教程 https://blog.csdn.net/Hanani_Jia/article/details/77950594

  5. github README.md教程

    github README.md教程 总结 github中README.md通过特殊字符标记和缩进来达到格式控制,也可以用HTML标签来实现格式控制. 教程一: Markdown 的目标是实现「易读易 ...

  6. github简单使用教程

    github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开.对于一般人来说公共仓库就已经足够了,而且我们也没多少代码来管理,O(∩_∩)O ...

  7. github简单使用教程(转)

    github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开.对于一般人来说公共仓库就已经足够了,而且我们也没多少代码来管理,O(∩_∩)O ...

  8. Xcode和github入门详细教程

    Xcode和github详细教程! 主要是参考了现在网上的一些资料给没整过的人一个详细的指南. (1)先在github上注册账号,自行解决! (2)在导航栏右上角new一个repository(仓库) ...

  9. (转载)github简单使用教程

    github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开.对于一般人来说公共仓库就已经足够了,而且我们也没多少代码来管理,O(∩_∩)O ...

  10. 从Git到GitHub,详细教程

    众所周知,一个稍微有点规模的项目,都不可能是一个人单打独斗完成的(能完成的大神别打我),所以,一个高效的项目团队就需要一个NB的工具来进行有效的交流(曾经有人问我企鹅不就可以吗,我竟无言以对),今天就 ...

随机推荐

  1. STM32F401的PWM输出

    PWM的说明 PWM有三个关键指标: PWM频率, 占空比, 区分度 对于同一个时钟频率下工作的单片机, 区分度是和PWM工作频率相关的, 因为总频率是固定的, PWM工作频率越高, 留下给区分度的部 ...

  2. fold命令

    fold命令 fold命令用于限制文件列宽,其会从指定的文件里读取内容,将超过限定列宽的列加入增列字符后,输出到标准输出设备.若不指定任何文件名称,或是所给予的文件名为-,则fold命令会从标准输入设 ...

  3. Swoole从入门到入土(15)——WebSocket服务器[初步接触]

    WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议.换句话说,Websocket让web可以与服务端实现长连接. 在Swoole中,通过内置的 WebSock ...

  4. 谈谈Tomcat占用cpu高的问题

    目录 问题现场 线程死锁 vs 线程死循环 排查Java进程导致CPU持续高的方法 Tomcat的CPU占用高的原因总结 问题现场 测试环境tomcat进程占用CPU一直持续99%,但是通过jstac ...

  5. 并发慎用——System.currentTimeMillis()

    好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受. System.currentTimeMillis()是极其常用的基础Java API,广泛地用来获取时间戳或测量代码 ...

  6. 硬件开发笔记(八): 硬件开发基本流程,制作一个USB转RS232的模块(七):创建基础DIP元器件(晶振)封装并关联原理图元器件

    前言   有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的.为了更好的表述封装设计过程,本文描述了创建晶振封装(DIP),将原理图的 ...

  7. 硬件开发笔记(七): 硬件开发基本流程,制作一个USB转RS232的模块(六):创建0603封装并关联原理图元器件

    前言   有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的.为了更好的表述封装设计过程,本文描述了贴片电阻电容0603芯片封装,创建 ...

  8. OpenCV开发笔记(五十九):红胖子8分钟带你深入了解分水岭算法(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  9. 红胖子(红模仿)的博文大全:开发技术集合大版本更新v4.0.0

    <红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术.树莓派.三维.OpenCV.OpenGL.ffmpeg.OSG.单片机.软硬结合等等)持续更新中...>大版本更新,更新后版本 ...

  10. 【LeetCode链表#11】环形链表II(双指针)

    环形链表II 力扣题目链接(opens new window) 题意: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,使用整数 pos 来表示 ...