美文网首页
golang后端开发之gin实例初始化配置

golang后端开发之gin实例初始化配置

作者: jojo1313 | 来源:发表于2022-09-04 17:40 被阅读0次

    基于ferry项目学习总结
    代码地址:https://gitee.com/yllan/ferry
    r := gin.New()

    request,response后端服务常规配置

    r.Use(LoggerToFile()) 记录请求日志(starttime,latencytime,cip, requestMethod, Uri)

    func LoggerToFile() gin.HandlerFunc {
        return func(c *gin.Context) {
            // 开始时间
            startTime := time.Now()
            // 处理请求
            c.Next()
            // 结束时间
            endTime := time.Now()
            // 执行时间
            latencyTime := endTime.Sub(startTime)
            // 请求方式
            reqMethod := c.Request.Method
            // 请求路由
            reqUri := c.Request.RequestURI
            // 状态码
            statusCode := c.Writer.Status()
            // 请求IP
            clientIP := c.ClientIP()
            // 日志格式
            logger.Infof(" %s %3d %13v %15s %s %s",
                startTime.Format("2006-01-02 15:04:05.9999"),
                statusCode,
                latencyTime,
                clientIP,
                reqMethod,
                reqUri,
            )
        }
    }
    

    r.Use(CustomError) 自定义错误处理

    func CustomError(c *gin.Context) {
        defer func() {
                    //如当前context被终止返回true
            if err := recover(); err != nil {
                if c.IsAborted() {
                    c.Status(200)
                }
                switch errStr := err.(type) {
                case string:
                    p := strings.Split(errStr, "#")
                    if len(p) == 3 && p[0] == "CustomError" {
                        statusCode, e := strconv.Atoi(p[1])
                        if e != nil {
                            break
                        }
                        c.Status(statusCode)
                        fmt.Println(
                            time.Now().Format("\n 2006-01-02 15:04:05.9999"),
                            "[ERROR]",
                            c.Request.Method,
                            c.Request.URL,
                            statusCode,
                            c.Request.RequestURI,
                            c.ClientIP(),
                            p[2],
                        )
                        c.JSON(http.StatusOK, gin.H{
                            "code": statusCode,
                            "msg":  p[2],
                        })
                    }
                default:
                    panic(err)
                }
            }
        }()
        c.Next()
    }
    

    r.Use(NoCache) 设置no-cache

    func NoCache(c *gin.Context) {
        c.Header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
        c.Header("Expires", "Thu, 01 Jan 1970 00:00:00 GMT")
        c.Header("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
        c.Next()
    }
    

    r.Use(Options) 支持跨域请求

    func Options(c *gin.Context) {
        if c.Request.Method != "OPTIONS" {
            c.Next()
        } else {
            c.Header("Access-Control-Allow-Origin", "*")
            c.Header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
            c.Header("Access-Control-Allow-Headers", "authorization, origin, content-type, accept")
            c.Header("Allow", "HEAD,GET,POST,PUT,PATCH,DELETE,OPTIONS")
            c.Header("Content-Type", "application/json")
            c.AbortWithStatus(200)
        }
    }
    

    r.Use(Secure) 设置Header安全策略

    func Secure(c *gin.Context) {
        c.Header("Access-Control-Allow-Origin", "*")
        //c.Header("X-Frame-Options", "DENY")
        c.Header("X-Content-Type-Options", "nosniff")
        c.Header("X-XSS-Protection", "1; mode=block")
        if c.Request.TLS != nil {
            c.Header("Strict-Transport-Security", "max-age=31536000")
        }
    
        // Also consider adding Content-Security-Policy headers
        // c.Header("Content-Security-Policy", "script-src 'self' https://cdnjs.cloudflare.com")
    }
    

    r.Use(RequestId()) 设置X-Request-Id,主要用于日志分析

    func RequestId() gin.HandlerFunc {
        return func(c *gin.Context) {
            // Check for incoming header, use it if exists
            requestId := c.Request.Header.Get("X-Request-Id")
            // Create request id with UUID4
            if requestId == "" {
                u4 := uuid.NewV4()
                requestId = u4.String()
            }
            // Expose it for use in the application
            c.Set("X-Request-Id", requestId)
            c.Writer.Header().Set("X-Request-Id", requestId)
            c.Next()
        }
    }
    

    相关文章

      网友评论

          本文标题:golang后端开发之gin实例初始化配置

          本文链接:https://www.haomeiwen.com/subject/zcbagrtx.html