请移步到我的Blog,获得更好的阅读体验!本文的链接请点这里
我的blog的文章是使用gitbook关联github仓库,用gitbook写文章,然后push到github。这就产生了问题,怎么把文章关联到我的blog呢?这就需要使用GitHub的 Webhooks了。
GitHub Webhooks
Webhooks是GitHub提供的一个API。Webhooks可以在GitHub仓库(repositories)发生事件(比如提交代码,创建分支,发布版本)时,通知到其他服务器。官方介绍点这里
用途
Webhooks可以用来触发CI,更新备份,更新生产环境等。
怎么使用GitHub Webhooks?
我们需要创建一个web服务器来接收Webhooks的请求,这里我使用nodejs来搭建:
const polka = require('polka');
const crypto = require('crypto');
const { json } = require('body-parser');
polka()
.use(json())
.post('/github-webhooks', (req, res) => {
res.writeHead(200);
res.end('webhooks success');
})
.listen(4000, err => {
if (err) throw err;
console.log(`> Running on localhost:4000`);
});
{% hint style="info" %}
polka是一个很小的http服务器,这里当成express来使用就可以了
{% endhint %}
很简单的一个例子,接收post
请求,返回'webhooks success',具体业务就不写啦。
接下来,需要打开我们的GitHub仓库界面,点这里的Settings
:
[图片上传失败...(image-f20c94-1563087198853)]
然后再点左侧栏的Webhooks
,右边有Add werbhook
按钮,点击增加Webhook
:
[图片上传失败...(image-8eda08-1563087198853)]
Payload URL
中输入我们的接口地址
Content type
选择application/json
Secret
是用来做加密验证的,可以随便填一些字符串,我们这里推荐填随机生成的字符串.也就是当GitHub访问我们的接口时会带上签名,我们的服务器需要进行验证,验证通过才能执行业务逻辑
输入完成后,点击下面的绿色Add webpack
按钮,GitHub会ping我们的接口,测试我们的接口能不能正常接收请求.
这个页面下面就出现一条ping的请求,可以看到,我们的例子接口是可以正常请求的。
[图片上传失败...(image-ef221d-1563087198853)]
Secret签名验证怎么做?
我们在GitHub上输入Secret后,需要在服务器中去验证签名,GitHub签名是使用 HMAC 来做加密验证的,我们需要把GitHub的hook传递过来的request.body转成字符串,然后去进行加密,加密后得到的字符串去跟请求头中的`x-hub-signature`参数做比较,如果一致则验证通过。下面是nodejs的代码实现:
const polka = require('polka');
const crypto = require('crypto');
const crypto = require('crypto');
const { json } = require('body-parser');
const SECRET_TOKEN = '在Secret中输入的字符串'
polka()
.use(json())
.post('/github-webhooks', (req, res) => {
const reg = /^sha1=/;
let sha1 = req.headers['x-hub-signature'];
if (reg.test(sha1)) {
sha1 = sha1.replace(reg, '');
const payload = JSON.stringify(req.body);
const hash = crypto.createHmac('sha1', SECRET_TOKEN).update(payload);
const token = hash.digest('hex');
if (token !== sha1) {
res.writeHead(401)
res.end('unauthorized');
return;
}
res.writeHead(200);
res.end('webhooks success');
return;
} else {
res.writeHead(401)
res.end('unauthorized');
return;
}
})
.listen(4000, err => {
if (err) throw err;
console.log(`> Running on localhost:4000`);
});
这样,加密签名验证就完成啦。
后面会分享关于GitHub的release和tags的hook使用,当前就结束啦