代码拉取完成,页面将自动刷新
package safety
import (
"context"
"encoding/json"
"errors"
"fmt"
"gitee.com/bobo-rs/innovideo-services/consts"
"gitee.com/bobo-rs/innovideo-services/enums"
"gitee.com/bobo-rs/innovideo-services/library/models"
"log"
"time"
)
// GetSign 获取安全密钥签名
func (s *sSafety) GetSign(ctx context.Context, tag enums.SafeTags) (*models.SafeSignItem, error) {
// 并发限制
var (
item = &models.SafeSignItem{
Secret: s.Secret(tag), // 获取密钥-适用于用户端入参敏感数据加密,例如手机号、身份证等
}
secret = s.Secret(tag) // 生成签名密钥-缓存到服务端,用于加解密签名-不对外
)
// 验证规则
err := s.Validate(ctx, tag)
if err != nil {
return nil, err
}
// 签名参数转JSON
buffer, err := json.Marshal(models.SignItem{
Secret: item.Secret,
Timestamp: time.Now().Add(time.Minute * 10).Unix(), // 十分钟
Nonce: s.Shuffle(),
})
if err != nil {
return nil, fmt.Errorf(`生成签名转换Json失败,请重试,%s`, err.Error())
}
// 生成签名
item.Sign, err = s.AESHandler(secret).EncryptString(buffer)
if err != nil {
return nil, fmt.Errorf(`生成签名失败,%s`, err.Error())
}
// 设置Tag密钥缓存
err = s.SetTagCache(ctx, tag, secret)
return item, err
}
// Verify 验证签名并解密签名值
func (s *sSafety) Verify(ctx context.Context, sign string, tag enums.SafeTags, isRemove ...bool) (*models.SignItem, error) {
// 获取加密密钥
secret, err := s.GetSecretTagMac(ctx, tag)
if err != nil {
return nil, err
}
// 签名解密
buff, err := s.Decrypt(sign, *secret)
if err != nil {
return nil, fmt.Errorf(`签名验证失败,%s`, err.Error())
}
// 转换为JSON
decoder := s.ToJson(buff)
// 解析JSON,是否JSON字串
if decoder.More() == false {
return nil, errors.New(`签名验证不通过`)
}
// 转换签名数据
item := &models.SignItem{}
if err = decoder.Decode(&item); err != nil {
return nil, err
}
// 验证是否过期
if item.Timestamp < time.Now().Unix() {
return nil, errors.New(`签名已过期,请重试`)
}
// 移除密钥,只能验证一次,验证之后即销毁
if len(isRemove) > 0 && isRemove[0] == true {
_ = s.RemoveSecretTagMac(ctx, tag)
}
return item, nil
}
// SetTagCache 设置安全密钥Tag缓存处理
func (s *sSafety) SetTagCache(ctx context.Context, tag enums.SafeTags, secret string) error {
// 设置密钥
err := s.SetSecretTagMac(ctx, tag, secret)
if err != nil {
return err
}
// 记录用户1分钟tag刷新数量
err = s.SetSecret1MinuteTagMacRefreshNum(ctx, tag)
// 记录用户1小时tag刷新数量
err = s.SetSecret1HourTagMacRefreshNum(ctx, tag)
// 记录1分钟刷新Tag量
err = s.SetSecret1MinuteTagRefreshNum(ctx, tag)
// 记录24小时刷新数量
err = s.SetSecret24HourTagRefreshNum(ctx, tag)
if err != nil {
log.Println(`设置缓存刷新数量报错`, err)
}
return nil
}
// Validate 验证安全密钥生成规则
func (s *sSafety) Validate(ctx context.Context, tag enums.SafeTags) error {
// 验证用户同一个Tag一分钟刷新次数
num, err := s.GetSecret1MinuteTagMacRefreshNum(ctx, tag)
if err != nil {
return err
}
// 验证规则
if consts.SafeSecret1MinuteRefreshLimitNumTagMac <= num {
return fmt.Errorf(`同一个Tag[%s]签名一分钟内刷新次数超过限制%d,稍后再试`, tag, num)
}
// 验证用户同一个Tag一小时刷新次数
num, err = s.GetSecret1HourTagMacRefreshNum(ctx, tag)
if err != nil {
return err
}
if consts.SafeSecret1HourRefreshLimitNumTagMac <= num {
return fmt.Errorf(`同一个Tag[%s]签名一小时内刷新次数超过限制%d,稍后再试`, tag, num)
}
// 同一个Tag一分钟刷新次数
num, err = s.GetSecret1MinuteTagRefreshNum(ctx, tag)
if err != nil {
return err
}
if consts.SafeSecret1MinuteRefreshLimitNumTag <= num {
return fmt.Errorf(`当前Tag[%s]服务签名一分钟内刷新次数超过限制%d,稍后再试`, tag, num)
}
// 同一个Tag24小时刷新次数
num, err = s.GetSecret24HourTagRefreshNum(ctx, tag)
if err != nil {
return err
}
if consts.SafeSecret24HourRefreshLimitNumTag <= num {
return fmt.Errorf(`当前Tag[%s]服务签名24小时内刷新次数超过限制%d,稍后再试`, tag, num)
}
return nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。