服务端 Webhook

GO-LANG Webhook

对于使用 go 的 Opencard 应用, 开发者可以参考以下 go 示例代码,来实现 Webhook的加解密功能。

  1. /* jwt 库
    * github地址:https://github.com/dvsekhvalnov/jose2go
    * 使用go的扩展安装方式安装 go get https://github.com/dvsekhvalnov/jose2go
    * 安装完成后即可使用
    */

如下文件是百度封装好的扩展,方便加密解密opencard数据操作

FILE: baidu/baidujwe.go

  1. package baidujwe

    import (
    "github.com/dvsekhvalnov/jose2go"
    "fmt"
    "encoding/json"
    "encoding/base64"
    "github.com/dvsekhvalnov/jose2go/compact"
    )


    func GetJweHeader(token_string string) (jwe_header map[string]interface{}, err error) {
    jh,err := getJweHeader(token_string)
    return jh, err
    }

    //通过jwe加密内容获取header 数据
    func getJweHeader(token_string string) (jwe_header map[string]interface{}, err error) {
    var jwtHeader map[string]interface{}
    parts, err := compact.Parse(token_string)
    if err != nil {
    return nil , err
    }
    header := parts[0]
    json.Unmarshal(header, &jwtHeader)
    fmt.Println(jwtHeader)
    return jwtHeader, nil
    }


    func GetReqParams(token_string string, psk string)(baidu_req map[string]interface{}, err error) {
    req_map, err := getReqParams(token_string, psk)
    return req_map, err
    }


    //通过psk 获取百度服务请求过来的参数内容
    func getReqParams(token_string string, psk string)(baidu_req map[string]interface{}, err error) {
    decodeBytes, _ := base64.RawURLEncoding.DecodeString(psk)
    var req_map map[string]interface{}
    req_parm, _, err := jose.Decode(token_string, decodeBytes)
    if err != nil {
    return nil, err
    }
    req_byte := []byte(req_parm)
    json.Unmarshal(req_byte, &req_map)
    return req_map, nil
    }


    func GetEncString(payload string, psk string, jwtHeader map[string]interface{}) (encString string, err error) {
    token, err := getEncString(payload, psk, jwtHeader)
    return token, err
    }

    // 加密要返回的数据

    func getEncString(payload string, psk string, jwtHeader map[string]interface{}) (encString string, err error) {
    psk_byte, err_1 := base64.RawURLEncoding.DecodeString(psk)
    if err_1 != nil {
    return "", err_1
    }
    token, err_2 := jose.Encrypt(payload, jose.A128KW, jose.A128CBC_HS256, psk_byte, jose.Headers(jwtHeader))
    if err_2 != nil {
    return "", err_2
    }
    return token, nil
    }

通过go 搭建一个简单的webhook 服务,示例仅用于开发参考,具体业务逻辑请开发人员自己处理

FILE : service/webhook.go

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
  1. package main

    import (
    "io"
    "io/ioutil"
    "net/http"
    "log"
    "baidu/baidujwe"//上文中的扩展
    "fmt"
    )

    func main() {
    http.HandleFunc("/", sayOne)
    //jwe测试路由
    http.HandleFunc("/hello", sayHello)
    // 路由注册完,开始运行
    err := http.ListenAndServe(":8889", nil)

    if err != nil {
    log.Fatal(err)
    }
    }

    func sayOne (w http.ResponseWriter, r http.Request) {
    io.WriteString(w, "this is version 1")
    }

    func sayHello (w http.ResponseWriter, r
    http.Request) {

    //开发者自己的psktable 内容
    psk_table := map[string]string{"1":"MDEyMzQ1Njc4OWFiY2RlZg","2":"MDEyMzQ1Njc4OWFiY2RlZg"}
    //获取来自百度的加密搜索请求
    s,
    := ioutil.ReadAll(r.Body)
    reqtoken := string(s)

    //通过获取的加密请求,获取jweheader 内容,并获取kid
    jwtHeader,
    := baidujwe.GetJweHeader(reqtoken)
    kid := jwtHeader["kid"].(string)

    //从psktable 中获得取相应的psk
    psk := psk_table[kid]
    fmt.Println(psk)

    //通过psk获取百度搜去请求的明文
    baidu_req,
    := baidujwe.GetReqParams(reqtoken, psk)
    //baidu_req 为一个map,具体使用,根据开发中业务逻辑开发
    fmt.Println(baidu_req)

    //业务数据
    str := {"title":"hello", "name":"word"}

    //加密业务数据
    token,
    := baidujwe.GetEncString(str, psk, jwtHeader)

    fmt.Println(token)

    //返回加密后的业务数据
    io.WriteString(w, token)
    }

完成上述开发后,运行服务

  1. 1
  1. go run webhook.go

使用文档中提供的jwe客户端进行测试 JWE客户端