feat: adjust api send token
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
)
|
||||
|
||||
//// getDeterministicSalt 根据字符串内容生成确定性 salt(范围 0~255)
|
||||
//func getDeterministicSalt(text string) byte {
|
||||
// var sum int
|
||||
// for i := 0; i < len(text); i++ {
|
||||
// sum = (sum + int(text[i])*(i+1)) & 0xFF
|
||||
// }
|
||||
// return byte(sum)
|
||||
//}
|
||||
|
||||
//// EncryptTokenHex 按照确定性 salt + 异或规则生成十六进制 token
|
||||
//// 规则:首字节为 salt;其余字节为 char ^ key ^ ((salt + idx) & 0xFF)
|
||||
//func EncryptTokenHex(text string, key byte) string {
|
||||
// salt := getDeterministicSalt(text)
|
||||
// // 预分配:2个hex字符的salt + 每个字符2个hex
|
||||
// out := make([]byte, 0, 2+len(text)*2)
|
||||
// // 写入salt
|
||||
// out = append(out, []byte(hex.EncodeToString([]byte{salt}))...)
|
||||
// // 写入加密数据
|
||||
// for i := 0; i < len(text); i++ {
|
||||
// b := text[i] ^ key ^ byte((int(salt)+i)&0xFF)
|
||||
// enc := make([]byte, 2)
|
||||
// hex.Encode(enc, []byte{b})
|
||||
// out = append(out, enc...)
|
||||
// }
|
||||
// return string(out)
|
||||
//}
|
||||
|
||||
// DecryptTokenHex 解析十六进制 token 为原始字符串
|
||||
// 规则:首字节为salt;后续字节与 key ^ ((salt + idx) & 0xFF) 异或
|
||||
func DecryptTokenHex(enc string, key byte) (string, error) {
|
||||
if enc == "" {
|
||||
return "", errors.New("empty token")
|
||||
}
|
||||
bs, err := hex.DecodeString(enc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(bs) < 1 {
|
||||
return "", errors.New("invalid token length")
|
||||
}
|
||||
salt := bs[0]
|
||||
out := make([]byte, len(bs)-1)
|
||||
for i := 1; i < len(bs); i++ {
|
||||
out[i-1] = bs[i] ^ key ^ byte((int(salt)+i-1)&0xFF)
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
@@ -2,16 +2,21 @@ package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"message-nest/pkg/app"
|
||||
"message-nest/pkg/e"
|
||||
utilpkg "message-nest/pkg/util"
|
||||
"message-nest/service/send_message_service"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type SendMessageReq struct {
|
||||
TaskID string `json:"task_id" validate:"required,len=12" label:"任务id"`
|
||||
// 兼容旧参数:task_id;不再必填
|
||||
TaskID string `json:"task_id" validate:"omitempty,len=12" label:"任务id"`
|
||||
// 新参数:token(与task_id互斥,优先使用task_id)
|
||||
Token string `json:"token" label:"任务token"`
|
||||
Text string `json:"text" validate:"required" label:"文本内容"`
|
||||
Title string `json:"title" label:"消息标题"`
|
||||
HTML string `json:"html" label:"html内容"`
|
||||
@@ -33,14 +38,31 @@ func DoSendMassage(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 解析token为task_id(如提供)
|
||||
taskID := req.TaskID
|
||||
// 如果使用了token就使用token解析出task_id
|
||||
if req.Token != "" {
|
||||
dec, err := utilpkg.DecryptTokenHex(req.Token, 71) // 71 为简单对称密钥
|
||||
if err != nil {
|
||||
appG.CResponse(http.StatusBadRequest, fmt.Sprintf("token解析失败:%v", err), nil)
|
||||
return
|
||||
}
|
||||
taskID = dec
|
||||
}
|
||||
|
||||
if taskID == "" {
|
||||
appG.CResponse(http.StatusBadRequest, "参数缺失:token 或 task_id 必须提供其一", nil)
|
||||
return
|
||||
}
|
||||
|
||||
msgService := send_message_service.SendMessageService{
|
||||
TaskID: req.TaskID,
|
||||
Title: req.Title,
|
||||
Text: req.Text,
|
||||
HTML: req.HTML,
|
||||
URL: req.URL,
|
||||
MarkDown: req.MarkDown,
|
||||
CallerIp: c.ClientIP(),
|
||||
TaskID: taskID,
|
||||
Title: req.Title,
|
||||
Text: req.Text,
|
||||
HTML: req.HTML,
|
||||
URL: req.URL,
|
||||
MarkDown: req.MarkDown,
|
||||
CallerIp: c.ClientIP(),
|
||||
DefaultLogger: logrus.WithFields(logrus.Fields{
|
||||
//"prefix": "[Message Instance]",
|
||||
}),
|
||||
|
||||
+22
-1
@@ -6,8 +6,29 @@ const gethttpOrigin = () => {
|
||||
|
||||
class ApiStrGenerate {
|
||||
|
||||
// 根据字符串内容生成确定性 salt(范围 0~255)
|
||||
static getDeterministicSalt(text) {
|
||||
let sum = 0;
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
sum = (sum + text.charCodeAt(i) * (i + 1)) & 0xFF;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
// 加密:首字节为salt,后续为按位异或后的数据
|
||||
static encryptHex(text, key) {
|
||||
const salt = ApiStrGenerate.getDeterministicSalt(text);
|
||||
let result = salt.toString(16).padStart(2, '0');
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const code = text.charCodeAt(i) ^ (key & 0xFF) ^ ((salt + i) & 0xFF);
|
||||
result += code.toString(16).padStart(2, '0');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static getDataString(task_id, options) {
|
||||
let data = { task_id: task_id };
|
||||
// 新版仅展示 token;兼容旧版 task_id(后端依然支持)
|
||||
let data = { token: ApiStrGenerate.encryptHex(task_id, 71) };
|
||||
data.title = 'message title';
|
||||
data.text = 'Hello World!';
|
||||
if (options.html) {
|
||||
|
||||
Reference in New Issue
Block a user