github.com/openimsdk/tools@v0.0.49/mw/gin.go (about)

     1  // Copyright © 2023 OpenIM. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package mw
    16  
    17  import (
    18  	"github.com/golang-jwt/jwt/v4"
    19  	"github.com/openimsdk/tools/log"
    20  	"github.com/openimsdk/tools/tokenverify"
    21  	"net/http"
    22  	"strings"
    23  
    24  	"github.com/gin-gonic/gin"
    25  	"github.com/openimsdk/protocol/constant"
    26  	"github.com/openimsdk/tools/apiresp"
    27  	"github.com/openimsdk/tools/errs"
    28  )
    29  
    30  // CorsHandler gin cross-domain configuration.
    31  func CorsHandler() gin.HandlerFunc {
    32  	return func(c *gin.Context) {
    33  		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
    34  		c.Header("Access-Control-Allow-Methods", "*")
    35  		c.Header("Access-Control-Allow-Headers", "*")
    36  		c.Header(
    37  			"Access-Control-Expose-Headers",
    38  			"Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar",
    39  		) // Cross-domain key settings allow browsers to resolve.
    40  		c.Header(
    41  			"Access-Control-Max-Age",
    42  			"172800",
    43  		) // Cache request information in seconds.
    44  		c.Header(
    45  			"Access-Control-Allow-Credentials",
    46  			"false",
    47  		) //  Whether cross-domain requests need to carry cookie information, the default setting is true.
    48  		c.Header(
    49  			"content-type",
    50  			"application/json",
    51  		) // Set the return format to json.
    52  		// Release all option pre-requests
    53  		if c.Request.Method == http.MethodOptions {
    54  			c.JSON(http.StatusOK, "Options Request!")
    55  			c.Abort()
    56  			return
    57  		}
    58  		c.Next()
    59  	}
    60  }
    61  
    62  func GinParseOperationID() gin.HandlerFunc {
    63  	return func(c *gin.Context) {
    64  		if c.Request.Method == http.MethodPost {
    65  			operationID := c.Request.Header.Get(constant.OperationID)
    66  			if operationID == "" {
    67  				err := errs.New("header must have operationID")
    68  				apiresp.GinError(c, errs.ErrArgs.WrapMsg(err.Error()))
    69  				c.Abort()
    70  				return
    71  			}
    72  			c.Set(constant.OperationID, operationID)
    73  		}
    74  		c.Next()
    75  	}
    76  }
    77  
    78  func GinParseToken(secretKey jwt.Keyfunc, whitelist []string) gin.HandlerFunc {
    79  	return func(c *gin.Context) {
    80  		switch c.Request.Method {
    81  		case http.MethodPost:
    82  			for _, wApi := range whitelist {
    83  				if strings.HasPrefix(c.Request.URL.Path, wApi) {
    84  					c.Next()
    85  					return
    86  				}
    87  			}
    88  
    89  			token := c.Request.Header.Get(constant.Token)
    90  			if token == "" {
    91  				apiresp.GinError(c, errs.ErrArgs.WrapMsg("header must have token"))
    92  				c.Abort()
    93  				return
    94  			}
    95  
    96  			claims, err := tokenverify.GetClaimFromToken(token, secretKey)
    97  			if err != nil {
    98  				log.ZWarn(c, "header get token error", errs.ErrArgs.WrapMsg("header must have token"))
    99  				apiresp.GinError(c, errs.ErrArgs.WrapMsg("header must have token"))
   100  				c.Abort()
   101  				return
   102  			}
   103  
   104  			c.Set(constant.OpUserPlatform, constant.PlatformIDToName(claims.PlatformID))
   105  			c.Set(constant.OpUserID, claims.UserID)
   106  			c.Next()
   107  		}
   108  	}
   109  }
   110  
   111  func CreateToken(userID string, accessSecret string, accessExpire int64, platformID int) (string, error) {
   112  	claims := tokenverify.BuildClaims(userID, platformID, accessExpire)
   113  	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
   114  	tokenString, err := token.SignedString([]byte(accessSecret))
   115  	if err != nil {
   116  		return "", errs.WrapMsg(err, "token.SignedString")
   117  	}
   118  	return tokenString, nil
   119  }