增加飞书webhook监听处理
This commit is contained in:
parent
6bfcc53073
commit
e101afccc6
|
@ -2,19 +2,12 @@ package logic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"fusenapi/server/feishu-sync/internal/svc"
|
||||||
"fmt"
|
"fusenapi/utils/feishu"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"fusenapi/server/feishu-sync/internal/svc"
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebhookLogic struct {
|
type WebhookLogic struct {
|
||||||
|
@ -62,7 +55,7 @@ func (l *WebhookLogic) Webhook(w http.ResponseWriter, r *http.Request) {
|
||||||
timestamp := r.Header.Get("X-Lark-Request-Timestamp")
|
timestamp := r.Header.Get("X-Lark-Request-Timestamp")
|
||||||
nonce := r.Header.Get("X-Lark-Request-Nonce")
|
nonce := r.Header.Get("X-Lark-Request-Nonce")
|
||||||
signature := r.Header.Get("X-Lark-Signature")
|
signature := r.Header.Get("X-Lark-Signature")
|
||||||
sign := l.CalculateFeiShuWebhookSignature(timestamp, nonce, l.svcCtx.Config.FeiShu.EncryptKey, bodyBytes)
|
sign := feishu.CalculateFeiShuWebhookSignature(timestamp, nonce, l.svcCtx.Config.FeiShu.EncryptKey, bodyBytes)
|
||||||
if signature != sign {
|
if signature != sign {
|
||||||
logx.Error("非法的消息,签名验证不通过", sign, "====", signature)
|
logx.Error("非法的消息,签名验证不通过", sign, "====", signature)
|
||||||
return
|
return
|
||||||
|
@ -77,7 +70,7 @@ func (l *WebhookLogic) Webhook(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//解密
|
//解密
|
||||||
realMsgBytes, err := l.DecryptFeiShuWebhookMsg(encryptMsg.Encrypt, l.svcCtx.Config.FeiShu.EncryptKey)
|
realMsgBytes, err := feishu.DecryptFeiShuWebhookMsg(encryptMsg.Encrypt, l.svcCtx.Config.FeiShu.EncryptKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return
|
return
|
||||||
|
@ -126,51 +119,3 @@ func (l *WebhookLogic) Webhook(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算签名
|
|
||||||
func (l *WebhookLogic) CalculateFeiShuWebhookSignature(timestamp, nonce, encryptKey string, body []byte) string {
|
|
||||||
var b strings.Builder
|
|
||||||
b.WriteString(timestamp)
|
|
||||||
b.WriteString(nonce)
|
|
||||||
b.WriteString(encryptKey)
|
|
||||||
b.Write(body) //bodystring 指整个请求体,不要在反序列化后再计算
|
|
||||||
bs := []byte(b.String())
|
|
||||||
h := sha256.New()
|
|
||||||
h.Write(bs)
|
|
||||||
bs = h.Sum(nil)
|
|
||||||
sig := fmt.Sprintf("%x", bs)
|
|
||||||
return sig
|
|
||||||
}
|
|
||||||
|
|
||||||
// 解密事件消息
|
|
||||||
func (l *WebhookLogic) DecryptFeiShuWebhookMsg(encryptData string, encryptKey string) ([]byte, error) {
|
|
||||||
buf, err := base64.StdEncoding.DecodeString(encryptData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("base64StdEncode Error[%v]", err)
|
|
||||||
}
|
|
||||||
if len(buf) < aes.BlockSize {
|
|
||||||
return nil, errors.New("cipher too short")
|
|
||||||
}
|
|
||||||
keyBs := sha256.Sum256([]byte(encryptKey))
|
|
||||||
block, err := aes.NewCipher(keyBs[:sha256.Size])
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("AESNewCipher Error[%v]", err)
|
|
||||||
}
|
|
||||||
iv := buf[:aes.BlockSize]
|
|
||||||
buf = buf[aes.BlockSize:]
|
|
||||||
// CBC mode always works in whole blocks.
|
|
||||||
if len(buf)%aes.BlockSize != 0 {
|
|
||||||
return nil, errors.New("ciphertext is not a multiple of the block size")
|
|
||||||
}
|
|
||||||
mode := cipher.NewCBCDecrypter(block, iv)
|
|
||||||
mode.CryptBlocks(buf, buf)
|
|
||||||
n := strings.Index(string(buf), "{")
|
|
||||||
if n == -1 {
|
|
||||||
n = 0
|
|
||||||
}
|
|
||||||
m := strings.LastIndex(string(buf), "}")
|
|
||||||
if m == -1 {
|
|
||||||
m = len(buf) - 1
|
|
||||||
}
|
|
||||||
return buf[n : m+1], nil
|
|
||||||
}
|
|
||||||
|
|
44
utils/feishu/decrypt.go
Normal file
44
utils/feishu/decrypt.go
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
package feishu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 解密事件消息
|
||||||
|
func DecryptFeiShuWebhookMsg(encryptData string, encryptKey string) ([]byte, error) {
|
||||||
|
buf, err := base64.StdEncoding.DecodeString(encryptData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("base64StdEncode Error[%v]", err)
|
||||||
|
}
|
||||||
|
if len(buf) < aes.BlockSize {
|
||||||
|
return nil, errors.New("cipher too short")
|
||||||
|
}
|
||||||
|
keyBs := sha256.Sum256([]byte(encryptKey))
|
||||||
|
block, err := aes.NewCipher(keyBs[:sha256.Size])
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("AESNewCipher Error[%v]", err)
|
||||||
|
}
|
||||||
|
iv := buf[:aes.BlockSize]
|
||||||
|
buf = buf[aes.BlockSize:]
|
||||||
|
// CBC mode always works in whole blocks.
|
||||||
|
if len(buf)%aes.BlockSize != 0 {
|
||||||
|
return nil, errors.New("ciphertext is not a multiple of the block size")
|
||||||
|
}
|
||||||
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
|
mode.CryptBlocks(buf, buf)
|
||||||
|
n := strings.Index(string(buf), "{")
|
||||||
|
if n == -1 {
|
||||||
|
n = 0
|
||||||
|
}
|
||||||
|
m := strings.LastIndex(string(buf), "}")
|
||||||
|
if m == -1 {
|
||||||
|
m = len(buf) - 1
|
||||||
|
}
|
||||||
|
return buf[n : m+1], nil
|
||||||
|
}
|
22
utils/feishu/verify.go
Normal file
22
utils/feishu/verify.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package feishu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 计算签名
|
||||||
|
func CalculateFeiShuWebhookSignature(timestamp, nonce, encryptKey string, body []byte) string {
|
||||||
|
var b strings.Builder
|
||||||
|
b.WriteString(timestamp)
|
||||||
|
b.WriteString(nonce)
|
||||||
|
b.WriteString(encryptKey)
|
||||||
|
b.Write(body) //bodystring 指整个请求体,不要在反序列化后再计算
|
||||||
|
bs := []byte(b.String())
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write(bs)
|
||||||
|
bs = h.Sum(nil)
|
||||||
|
sig := fmt.Sprintf("%x", bs)
|
||||||
|
return sig
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user