智能小程序OPENCARD
接入指南

服务端 Webhook

GO-LANG Webhook

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

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

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

FILE: baidu/baidujwe.go

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
60
61
62
63
64
65
66
67
68
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
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
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) {

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

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

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

//通过psk获取百度搜去请求的明文
baidu_req, _ := baidujwe.GetReqParams(req_token, 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
go run webhook.go

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

反 馈帮 助 回 到顶 部