修改对应app的参数结构

This commit is contained in:
2024-04-09 13:38:29 +08:00
parent 8b7b138ca2
commit 578d7ecdf9
16 changed files with 605 additions and 78 deletions

10
utils/basic/error_code.go Normal file
View File

@@ -0,0 +1,10 @@
package basic
type ErrorCode struct {
Code int `json:"code"`
Message string `json:"message"`
}
var (
ErrParamParse = &ErrorCode{Code: 10100, Message: "参数解析错误"}
)

41
utils/basic/types.go Normal file
View File

@@ -0,0 +1,41 @@
package basic
// 全局返回的结构体
type Response struct {
Data interface{} `json:"data"`
ErrorCode int `json:"error_code"`
ErrorText string `json:"error_text"`
IsSuccess bool `json:"success"`
}
func (resp *Response) Error(errcode *ErrorCode, Data ...interface{}) {
resp.ErrorCode = errcode.Code
resp.ErrorText = errcode.Message
resp.IsSuccess = false
resp.setData(Data)
}
func (resp *Response) ErrorEx(Code int, Message string, Data ...interface{}) {
resp.ErrorCode = Code
resp.ErrorText = Message
resp.IsSuccess = false
resp.setData(Data)
}
func (resp *Response) Success(Data ...interface{}) {
resp.IsSuccess = true
resp.setData(Data)
}
func (resp *Response) setData(Data []interface{}) {
if len(Data) == 0 {
resp.Data = []interface{}{}
return
}
if len(Data) == 1 {
resp.Data = Data
} else {
resp.Data = Data
}
}

27
utils/cors/cors.go Normal file
View File

@@ -0,0 +1,27 @@
package cors
import (
"net/http"
"github.com/gin-gonic/gin"
)
func SetCors(router *gin.Engine) {
// 处理前端发送的options请求
router.OPTIONS("/*path", func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*") // 可以根据实际情况改为特定域名
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization")
c.Header("Access-Control-Allow-Credentials", "true")
c.Status(http.StatusOK)
})
// 处理所有的路由请求
router.Use(func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*") // 允许所有域名跨域访问,也可以指定特定的域名
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization")
c.Header("Access-Control-Allow-Credentials", "true")
c.Next()
})
}

View File

@@ -0,0 +1,4 @@
package encryption_decryption
// 必须16字节
var cbckey = "bjwl20240409"

View File

@@ -0,0 +1,106 @@
package encryption_decryption
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/gob"
"sync"
)
type ISecretEncDec interface {
EncodeToString([]byte) string
DecodeString(string) ([]byte, error)
}
type SecretCRT[T any] struct {
srcKey string
secretKey []byte
iv []byte
derivationKey func(keysting string) []byte
mu sync.Mutex
EncDec ISecretEncDec
}
func NewSecretCRT[T any](key string, iv string) *SecretCRT[T] {
if key == "" {
panic("NewSecretCRT key must not null")
}
s := &SecretCRT[T]{
derivationKey: DerivationKeyV1,
iv: []byte(iv),
EncDec: base64.RawURLEncoding,
}
s.secretKey = s.derivationKey(key)
return s
}
func (s *SecretCRT[T]) UpdateDerivationKeyFunc(kfunc func(keysting string) []byte) {
s.mu.Lock()
defer s.mu.Unlock()
s.derivationKey = kfunc
s.secretKey = s.derivationKey(s.srcKey)
}
func (s *SecretCRT[T]) Encrypt(gobj *T) (string, error) {
s.mu.Lock()
defer s.mu.Unlock()
var buf = bytes.NewBuffer(nil)
err := gob.NewEncoder(buf).Encode(gobj)
if err != nil {
return "", err
}
// 使用AES加密,返回一个Block接口
block, err := aes.NewCipher(s.secretKey)
if err != nil {
panic(err)
}
// 使用CTR模式
stream := cipher.NewCTR(block, s.iv)
// 加密明文
plaintext := buf.Bytes()
ciphertext := make([]byte, len(plaintext))
stream.XORKeyStream(ciphertext, plaintext)
// 转为hex编码打印出来
return s.EncDec.EncodeToString(ciphertext), nil
}
func (s *SecretCRT[T]) Decrypt(ciphertext string) (*T, error) {
// 将hex解码成[]byte
ciphertextbytes, err := s.EncDec.DecodeString(ciphertext)
if err != nil {
return nil, err
}
// 生成Block接口
block, err := aes.NewCipher(s.secretKey)
if err != nil {
panic(err)
}
// 生成CTR模式
stream := cipher.NewCTR(block, s.iv)
// 解密密文
plaintext := make([]byte, len(ciphertextbytes))
stream.XORKeyStream(plaintext, ciphertextbytes)
// 解出golang的结构体
var protected T
var buf = bytes.NewBuffer(plaintext)
err = gob.NewDecoder(buf).Decode(&protected)
if err != nil {
return nil, err
}
return &protected, nil
}

View File

@@ -0,0 +1,133 @@
package encryption_decryption
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"encoding/gob"
"fmt"
"io"
"sync"
)
func DerivationKeyV1(keysting string) []byte {
key := []byte(keysting)
var result [16]byte
// If key length is more than 32, truncate it
if len(key) > 16 {
key = key[:16]
}
// If key length is less than 32, replicate it until it reaches 32
for len(key) < 16 {
key = append(key, key...)
}
// Only take the first 32 bytes
key = key[:16]
// Swap the first 16 bytes with the last 16 bytes
copy(result[:], key[8:])
copy(result[8:], key[:8])
return result[:]
}
type SecretGCM[T any] struct {
srcKey string
secretKey []byte
derivationKey func(keysting string) []byte
mu sync.Mutex
EncDec ISecretEncDec
}
func NewSecretGCM[T any](key string) *SecretGCM[T] {
if key == "" {
panic("NewSecretGCM key must not null")
}
s := &SecretGCM[T]{
srcKey: key,
derivationKey: DerivationKeyV1,
EncDec: base64.RawURLEncoding,
}
s.secretKey = s.derivationKey(s.srcKey)
return s
}
func (s *SecretGCM[T]) UpdateDerivationKeyFunc(kfunc func(keysting string) []byte) {
s.mu.Lock()
defer s.mu.Unlock()
s.derivationKey = kfunc
s.secretKey = s.derivationKey(s.srcKey)
}
func (s *SecretGCM[T]) Encrypt(gobj *T) (string, error) {
s.mu.Lock()
defer s.mu.Unlock()
var buf = bytes.NewBuffer(nil)
err := gob.NewEncoder(buf).Encode(gobj)
if err != nil {
return "", err
}
block, err := aes.NewCipher(s.secretKey)
if err != nil {
return "", err
}
nonce := make([]byte, 12)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return "", err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
ciphertext := aesgcm.Seal(nonce, nonce, buf.Bytes(), nil)
return s.EncDec.EncodeToString(ciphertext), nil
}
func (s *SecretGCM[T]) Decrypt(ciphertext string) (*T, error) {
block, err := aes.NewCipher(s.secretKey)
if err != nil {
return nil, err
}
ct, err := s.EncDec.DecodeString(ciphertext)
if err != nil {
return nil, err
}
if len(ct) < 12 {
return nil, fmt.Errorf("ciphertext too short")
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
plaintext, err := aesgcm.Open(nil, ct[:12], ct[12:], nil)
if err != nil {
return nil, err
}
// 解出golang的结构体
var protected T
var buf = bytes.NewBuffer(plaintext)
err = gob.NewDecoder(buf).Decode(&protected)
if err != nil {
return nil, err
}
return &protected, nil
}

View File

@@ -0,0 +1,36 @@
package encryption_decryption
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"sort"
"strings"
)
func MakeSign(params map[string]interface{}) string {
// 排序
keys := make([]string, len(params))
i := 0
for k, _ := range params {
keys[i] = k
i++
}
sort.Strings(keys)
byteBuf := bytes.NewBuffer([]byte{})
encoder := json.NewEncoder(byteBuf)
encoder.SetEscapeHTML(false)
err := encoder.Encode(params)
if err != nil {
panic(err)
}
data := byteBuf.String()
h := md5.New()
h.Write([]byte(strings.TrimRight(data, "\n")))
return hex.EncodeToString(h.Sum(nil))
}