123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- package interceptor
- import (
- "net/http"
- "strings"
- "github.com/xinliangnote/go-gin-api/configs"
- "github.com/xinliangnote/go-gin-api/internal/code"
- "github.com/xinliangnote/go-gin-api/internal/pkg/core"
- "github.com/xinliangnote/go-gin-api/internal/repository/mysql/authorized"
- "github.com/xinliangnote/go-gin-api/pkg/env"
- "github.com/xinliangnote/go-gin-api/pkg/errors"
- "github.com/xinliangnote/go-gin-api/pkg/signature"
- "github.com/xinliangnote/go-gin-api/pkg/urltable"
- )
- var whiteListPath = map[string]bool{
- "/login/web": true,
- }
- func (i *interceptor) CheckSignature() core.HandlerFunc {
- return func(c core.Context) {
- if !env.Active().IsPro() {
- return
- }
- // 签名信息
- authorization := c.GetHeader(configs.HeaderSignToken)
- if authorization == "" {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(errors.New("Header 中缺少 Authorization 参数")),
- )
- return
- }
- // 时间信息
- date := c.GetHeader(configs.HeaderSignTokenDate)
- if date == "" {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(errors.New("Header 中缺少 Date 参数")),
- )
- return
- }
- // 通过签名信息获取 key
- authorizationSplit := strings.Split(authorization, " ")
- if len(authorizationSplit) < 2 {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(errors.New("Header 中 Authorization 格式错误")),
- )
- return
- }
- key := authorizationSplit[0]
- data, err := i.authorizedService.DetailByKey(c, key)
- if err != nil {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(err),
- )
- return
- }
- if data.IsUsed == authorized.IsUsedNo {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(errors.New(key + " 已被禁止调用")),
- )
- return
- }
- if len(data.Apis) < 1 {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(errors.New(key + " 未进行接口授权")),
- )
- return
- }
- if !whiteListPath[c.Path()] {
- // 验证 c.Method() + c.Path() 是否授权
- table := urltable.NewTable()
- for _, v := range data.Apis {
- _ = table.Append(v.Method + v.Api)
- }
- if pattern, _ := table.Mapping(c.Method() + c.Path()); pattern == "" {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(errors.New(c.Method() + c.Path() + " 未进行接口授权")),
- )
- return
- }
- }
- ok, err := signature.New(key, data.Secret, configs.HeaderSignTokenTimeout).Verify(authorization, date, c.Path(), c.Method(), c.RequestInputParams())
- if err != nil {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(err),
- )
- return
- }
- if !ok {
- c.AbortWithError(core.Error(
- http.StatusBadRequest,
- code.AuthorizationError,
- code.Text(code.AuthorizationError)).WithError(errors.New("Header 中 Authorization 信息错误")),
- )
- return
- }
- }
- }
|