golang gin接口签名sign

golang gin接口签名sign

	gin.Default().Group("").Use(xxx.CheckSign())
	{
		//注册需要签名的路由
		gin.Default().Group("testrouter").POST("dotest", func(ctx *gin.Context) {
			response.Result(401, gin.H{}, "hello", ctx)
		}) 
	}

sign.go 签名 验签

package xxx

import (
	"crypto/sha256"
	"encoding/hex"
	"fmt"

	"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
	"github.com/gin-gonic/gin"
)

var (
	SignWrong  = "sign wrong"
	SignNull   = "sign null"
	ApiKeyNull = "sign null"
	UserWrong  = "username wrong"
)

func CheckSign() gin.HandlerFunc {
	return func(c *gin.Context) {
		reqData := &RequestHttp{
			Ctx:    c,
			Params: map[string]interface{}{},
		}
		apiKey := c.Request.FormValue("api_key")
		if apiKey == "" {
			response.Result(401, gin.H{}, ApiKeyNull, c)
			c.Abort()
			return
		}
		apiSecret := ""
		signReq := c.Request.FormValue("sign")
		if signReq == "" {
			response.Result(401, gin.H{}, SignNull, c)
			c.Abort()
			return
		}
		signStr := reqData.RequestParams("sign") + apiSecret
		fmt.Println(signStr, "signStr")
		signReal := SignEncode(signStr)
		if signReq != signReal {
			response.Result(401, gin.H{}, SignWrong, c)
			c.Abort()
			return
		}
		c.Next()
	}
}

//@function: SignEncode
//@description: 生成sign
//@param: message string
//@return: sign string
func SignEncode(message string) string {
	return GetSHA256HashCode(message)
}

//@function: GetSHA256HashCode
//@description: SHA256生成哈希值
//@param: message string
//@return: hashCode string
func GetSHA256HashCode(message string) string {
	messageArr := []byte(message)
	//创建一个基于SHA256算法的hash.Hash接口的对象
	hash := sha256.New()
	//输入数据
	hash.Write(messageArr)
	//计算哈希值
	bytes := hash.Sum(nil)
	//将字符串编码为16进制格式,返回字符串
	hashCode := hex.EncodeToString(bytes)
	//返回哈希值
	return hashCode
}

get_request.go 获取请求参数,转换请求参数为string,参数key排序

package xxx

import (
	"fmt"
	"sort"
	"strings"
	"sync"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
)

type RequestHttp struct {
	Ctx    *gin.Context
	Params map[string]interface{}
	lock   sync.Mutex
}

//@function: JoinParamsStr
//@description: 请求参数转换字符串
//@param: message string
//@return: a=1&b=2 string
func (r *RequestHttp) JoinParamsStr() string {
	//先按key 排序 升序 ASCII 升序
	keys := make([]string, 0, len(r.Params))
	for k := range r.Params {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	var params []string
	if len(r.Params) > 0 {
		for _, k := range keys {
			params = append(params, fmt.Sprintf("%s=%v", k, r.Params[k]))
		}
	}
	return strings.Join(params, "&")
}

//@function: RequestParams
//@description: 获取参数集合
//@param: exclude string 排除key
//@return: hashCode string
func (r *RequestHttp) RequestParams(exclude string) string {
	ctx := r.Ctx
	bindParams := map[string]interface{}{}
	if ctx.Request.Method == "POST" {
		contextType := ctx.Request.Header.Get("Content-Type")
		if contextType == "application/json" {
			err := ctx.ShouldBindBodyWith(&bindParams, binding.JSON)
			if err != nil { //报错
				fmt.Printf("nyx_request_mid_error %v,err: %v \n", bindParams, err)
				return ""
			}
			if len(bindParams) > 0 {
				for k, v := range bindParams {
					r.Add(k, v)
				}
			}
		} else {
			_ = ctx.Request.ParseMultipartForm(32 << 20)
			if len(ctx.Request.PostForm) > 0 {
				for k, v := range ctx.Request.PostForm {
					r.Add(k, v[0])
				}
			}
		}
	} else {
		var tmpParams = make(map[string]string)
		err2 := ctx.ShouldBind(&tmpParams)
		if err2 != nil {
			fmt.Printf("nyx_request_mid_error %v,err: %v \n", bindParams, err2)
			return ""
		}
		for k, v := range tmpParams {
			r.Add(k, v)
		}
	}
	r.Delete(exclude)
	return r.JoinParamsStr()
}

//添加参数
func (r *RequestHttp) Add(key string, value interface{}) {
	r.lock.Lock()
	r.Params[key] = value
	r.lock.Unlock()
}

//删除参数
func (r *RequestHttp) Delete(key string) {
	r.lock.Lock()
	if _, ok := r.Params[key]; ok {
		delete(r.Params, key)
	}
	r.lock.Unlock()
}
### 使用 GolangGin 框架连接 MySQL 创建 API 接口 #### 创建并配置项目结构 为了构建一个基于Gin框架的应用程序,首先需要初始化一个新的Go模块: ```bash go mod init example.com/gin-mysql-api ``` 接着安装必要的依赖包: ```bash go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/mysql ``` #### 初始化数据库连接 在 `main.go` 文件中设置MySQL数据库的连接字符串,并利用GORM建立与数据库之间的会话。 ```go package main import ( "fmt" "gorm.io/driver/mysql" "gorm.io/gorm" ) var db *gorm.DB var err error func InitDB() { dsn := "user:password@tcp(127.0.0.1:3306)/gin_demo?charset=utf8mb4&parseTime=True&loc=Local" db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { fmt.Println("Failed to connect database:", err) panic(err) } } ``` 这段代码展示了如何打开到名为 `gin_demo` 的MySQL数据库的连接[^1]。请注意替换DSN中的用户名、密码和其他参数以匹配实际环境下的配置。 #### 定义模型层 (Model Layer) 假设要管理成员(`Member`)的数据,则可以在应用里定义相应的结构体来映射表字段。 ```go type Member struct { ID uint `json:"id"` Name string `json:"name" gorm:"not null"` Email string `json:"email" gorm:"uniqueIndex;not null"` CreatedAt time.Time UpdatedAt time.Time } ``` 此部分描述了实体类的设计原则及其属性约束条件[^2]。 #### 实现业务逻辑服务 (Service Layer) 编写服务于具体功能的服务函数,比如新增会员记录: ```go // CreateMember creates a new member record. func CreateMember(m *Member) (*Member, error) { result := db.Create(&m) if result.Error != nil { return nil, result.Error } return m, nil } ``` 上述片段说明了怎样封装基本的操作以便于后续调用。 #### 构建控制器 (Controller Layer) 最后一步是在HTTP请求处理器内实现对外暴露的功能端点。下面的例子实现了POST /members 路由用来接收客户端提交的新用户资料并保存至数据库。 ```go package controllers import ( "net/http" "github.com/gin-gonic/gin" ) func AddMember(c *gin.Context) { var input Member if err := c.ShouldBindJSON(&input); err == nil { createdMember, _ := service.CreateMember(&input) c.JSON(http.StatusOK, gin.H{"data": createdMember}) } else { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) } } func SetupRoutes(engine *gin.Engine) { v1 := engine.Group("/api/v1") { members := v1.Group("/members") { members.POST("", AddMember) } } } ``` 以上内容解释了如何通过组合先前各层次组件完成一次完整的API交互过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值