Github Webhooks實(shí)踐(Go語(yǔ)言)

項(xiàng)目需要,百度了一下Github Webhooks,內(nèi)容基本雷同,也沒有找到我想要的如下兩個(gè)功能說(shuō)明:

  • 提交時(shí)做了哪些變動(dòng)?
  • secret的使用
    查看原文

罷了,想拿來(lái)即用的偷懶之路走不通,只能老老實(shí)實(shí)啃官方文檔了。

Webhooks干嘛用的?

Github Webhooks提供了一堆事件,這些事件在用戶特定的操作下會(huì)被觸發(fā),比如創(chuàng)建分支(Branch)、庫(kù)被fork、項(xiàng)目被star、用戶push了代碼等等。
我們可以自己寫一個(gè)服務(wù),將服務(wù)的URL交給Webhooks,當(dāng)上述事件被觸發(fā)時(shí),Webhook會(huì)向這個(gè)服務(wù)發(fā)送一個(gè)POST請(qǐng)求,請(qǐng)求中附帶著該事件相關(guān)的詳細(xì)描述信息(即Payload)。
這樣,我們就可以在自己服務(wù)中知道Github的什么事件被觸發(fā)了,事件的內(nèi)容是什么?據(jù)此我們就可以干一些自己想干的事了。能干什么呢?官方說(shuō)You're only limited by your imagination,就是說(shuō)想干什么都行,就看你的想像力夠不夠 :)

Webhooks配置

進(jìn)入要hook的庫(kù)-->Settings-->Webhooks-->Add Webhook

add webhook

Add Webhook界面長(zhǎng)這樣:

add webhook UI

  • Payload URL
    就是我們用來(lái)接收事件詳情(Payload)的服務(wù)URL

  • Content type
    即Webhooks用什么樣的數(shù)據(jù)格式給我們發(fā)送Payload,Webhooks支持以下兩種類型的數(shù)據(jù)

    • application/json
    • application/x-www-form-urlencoded
  • Secret
    這里可以提供一個(gè)加密Key,Webhooks會(huì)以此key生成Payload的一個(gè)數(shù)字簽名隨POST請(qǐng)求發(fā)送給你,你可以通過(guò)此簽名驗(yàn)證數(shù)據(jù)的合法性。如何驗(yàn)證,見后文所附代碼。

  • Webhook event
    Webhooks事件的選擇項(xiàng):

    • Just the push event
      僅hook Push事件
    • Send me everything
      hook所有事件
    • Let me select indiidual event
      讓用戶自己選擇hook什么事件

    默認(rèn)是Just the push event.,我們不改了,用它得了。

Post了什么東東

在寫服務(wù)之前,我們先看看Webhooks給我們發(fā)送了什么。

  • Post Request Header

    Post Request Header

    • Request URL
      即前面配置中填寫的“Payload URL”
    • content-type
      即前面配置中選擇的“Content type”
    • X-Hub-Signature
      是對(duì)Payload計(jì)算得出的簽名。當(dāng)我們?cè)谇懊娴呐渲弥休斎肓恕癝ecret”后,Header中才會(huì)出現(xiàn)此項(xiàng)。官方文檔對(duì)Secret作了詳細(xì)說(shuō)明,后面我們也會(huì)在代碼中實(shí)現(xiàn)對(duì)它的校驗(yàn)。
  • Post Request Body

    Post Request Body

    這是觸發(fā)Push事件時(shí)Webhooks發(fā)給我們的Payload,藍(lán)色框中的內(nèi)容就是我期望得到的庫(kù)文件的變動(dòng)信息。很直白,不再解釋。有了數(shù)據(jù)結(jié)構(gòu),拿到想要的數(shù)據(jù)就不是難事了,所以后面代碼中也不會(huì)有這部分內(nèi)容了。

我們的服務(wù)怎么寫?

本文中使用Gin實(shí)現(xiàn)所需功能,代碼僅用于演示,請(qǐng)輕拍 :)

func Init(g *gin.Engine, mw ...gin.HandlerFunc) *gin.Engine {  
    // Middlewares.  
    g.Use(mw...)  

    // 404 處理  
    g.NoRoute(func(c *gin.Context) {  
        c.String(http.StatusNotFound, "The incorrect API route.")  
    })  

    // 路由  
    sv := g.Group("/sv")  
    {  
        sv.POST("/gitpush", gitpush)  
        // 其它路由定義......  
    }  

    return g  
}  

// Github Webhooks Post請(qǐng)求處理函數(shù)  
func gitpush(c *gin.Context) {  
    // 驗(yàn)證簽名  
    if matched, _ := verifySignature(c); !matched {  
        err := "Signatures didn't match!"  
        c.String(http.StatusForbidden, err)  
        fmt.Println(err)  
        return  
    }  

    fmt.Println("Signatures is match! go!")  

    // 你自己的業(yè)務(wù)邏輯......  

    c.String(http.StatusOK, "OK")  
}  

// 驗(yàn)證簽名  
func verifySignature(c *gin.Context) (bool, error) {  
    payloadBody, err := c.GetRawData()  
    if err != nil {  
        return false, err  
    }  

    // 獲取請(qǐng)求頭中的簽名信息  
    hSignature := c.GetHeader("X-Hub-Signature")  

    // 計(jì)算Payload簽名  
    signature := hmacSha1(payloadBody)  

    return (hSignature == signature), nil  

}  

// hmac-sha1  
func hmacSha1(payloadBody []byte) string {  
    h := hmac.New(sha1.New, []byte("password"))  
    h.Write(payloadBody)  
    return "sha1=" + hex.EncodeToString(h.Sum(nil))  
}  
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,715評(píng)論 19 139
  • 服務(wù)器:Jenkins Server Git Server App Server關(guān)鍵詞:nodejs ngrok ...
    趁你還年輕233閱讀 22,872評(píng)論 2 3
  • 我不記得我上一次完完整整的看完一本書是什么時(shí)候了。最近再次想到這個(gè)問(wèn)題的時(shí)候,是考慮到是否要開公眾號(hào)的事,最主要的...
    方予視界閱讀 311評(píng)論 0 3
  • 早晨上班的路上,突然看見家附近的大學(xué)校園里有許多穿著學(xué)士服拍照的學(xué)生們,這才想起原來(lái)已經(jīng)快六月了,一年一度的畢業(yè)季...
    秋天的野薔薇閱讀 220評(píng)論 0 0
  • 漠視別人時(shí),雖然在語(yǔ)言層面上沒傳遞任何信息,但心理層面上傳遞的信息是'你一點(diǎn)都不重要','我一點(diǎn)都看不上你'.
    心_聲閱讀 215評(píng)論 0 0

友情鏈接更多精彩內(nèi)容