千家信息网

Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章主要讲解了"Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来
千家信息网最后更新 2026年11月01日Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结

这篇文章主要讲解了"Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结"吧!

重定向

Gin返回一个HTTP重定向非常简单, 使用Redirect方法即可. 内部和外部链接都支持.

package main  import (   "github.com/gin-gonic/gin"   "net/http" )  func main() {   r := gin.Default()   r.GET("/test", func(c *gin.Context) {     c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")  //重定向到外部链接   })    //重定向到内部链接   r.GET("/internal", func(c *gin.Context) {     c.Redirect(http.StatusMovedPermanently, "/home")   })    r.GET("/home", func(c *gin.Context) {     c.JSON(200, gin.H{"msg": "这是首页"})   })   r.Run(":8080") }  /* 重定向到外部链接,访问:http://localhost:8080/test 重定向到内部链接,访问:http://localhost:8080/internal */

从POST方法中完成HTTP重定向, 参考问题#444 https://github.com/gin-gonic/gin/issues/444

r.POST("/test", func(c *gin.Context) {   c.Redirect(http.StatusFound, "/foo") })

如果要产生一个路由重定向, 类似上面的内部重定向, 则使用 HandleContext方法, 像下面这样使用:

r.GET("/test", func(c *gin.Context) {     c.Request.URL.Path = "/test2"     r.HandleContext(c) }) r.GET("/test2", func(c *gin.Context) {     c.JSON(200, gin.H{"hello": "world"}) })

自定义中间件

package main  import (   "github.com/gin-gonic/gin"   "log"   "time" )  //自定义日志中间件 func Logger() gin.HandlerFunc {   return func(c *gin.Context) {     t := time.Now()      // Set example variable 在gin上下文中设置键值对     c.Set("example", "12345")      // before request      //Next方法只能用于中间件中,在当前中间件中, 从方法链执行挂起的处理器     c.Next()      // after request  打印中间件执行耗时     latency := time.Since(t)     log.Print(latency)      // access the status we are sending  打印本中间件的状态码     status := c.Writer.Status()     log.Println(status)   } }  func main() {   r := gin.New()   //使用该自定义中间件   r.Use(Logger())   r.GET("/test", func(c *gin.Context) {     example := c.MustGet("example").(string) //从上下文中获取键值对     // it would print: "12345"     log.Println(example)   })    // Listen and serve on 0.0.0.0:8080   r.Run(":8080") }

使用基本认证BasicAuth()中间件

package main  import (   "github.com/gin-gonic/gin"   "net/http" )  // simulate some private data var secrets = gin.H{   "foo":    gin.H{"email": "foo@bar.com", "phone": "123433"},   "austin": gin.H{"email": "austin@example.com", "phone": "666"},   "lena":   gin.H{"email": "lena@guapa.com", "phone": "523443"}, }  func main() {   r := gin.Default()    // Group using gin.BasicAuth() middleware   // gin.Accounts is a shortcut for map[string]string   // 路由组authorized使用基本认证中间件, 参数为gin.Accounts,是一个map,键名是用户名, 键值是密码, 该中间件会将认证信息保存到cookie中   authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{     "foo":    "bar",     "austin": "1234",     "lena":   "hello2",     "manu":   "4321",   }))    // /admin/secrets endpoint   // hit "localhost:8080/admin/secrets   authorized.GET("/secrets", func(c *gin.Context) {     // get user, it was set by the BasicAuth middleware     // 从cookie中获取用户认证信息, 键名为user     user := c.MustGet(gin.AuthUserKey).(string)     if secret, ok := secrets[user]; ok {       c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})     } else {       c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})     }   })    // Listen and serve on 0.0.0.0:8080   r.Run(":8080") } /* 测试访问:http://localhost:8080/admin/secrets */

在中间件中使用协程Goroutines

在中间件或者控制器中启动新协程时, 不能直接使用原来的Gin上下文, 必须使用一个只读的上下文副本

package main  import (   "github.com/gin-gonic/gin"   "log"   "time" )  func main() {   r := gin.Default()    r.GET("/long_async", func(c *gin.Context) {     // create copy to be used inside the goroutine     // 创建一个Gin上下文的副本, 准备在协程Goroutine中使用     cCp := c.Copy()     go func() {       // simulate a long task with time.Sleep(). 5 seconds       // 模拟长时间任务,这里是5秒       time.Sleep(5 * time.Second)        // note that you are using the copied context "cCp", IMPORTANT       // 在中间件或者控制器中启动协程时, 不能直接使用原来的上下文, 必须使用一个只读的上线文副本       log.Println("Done! in path " + cCp.Request.URL.Path)     }()   })    r.GET("/long_sync", func(c *gin.Context) {     // simulate a long task with time.Sleep(). 5 seconds     time.Sleep(5 * time.Second)      // since we are NOT using a goroutine, we do not have to copy the context     // 没有使用协程时, 可以直接使用Gin上下文     log.Println("Done! in path " + c.Request.URL.Path)   })    // Listen and serve on 0.0.0.0:8080   r.Run(":8080") } /* 模拟同步阻塞访问:http://localhost:8080/long_sync 模拟异步非阻塞访问:http://localhost:8080/long_async */

自定义HTTP配置

直接使用 http.ListenAndServe()方法:

func main() {   router := gin.Default()   http.ListenAndServe(":8080", router) }

或者自定义HTTP配置

func main() {   router := gin.Default()    s := &http.Server{     Addr:           ":8080",     Handler:        router,     ReadTimeout:    10 * time.Second,     WriteTimeout:   10 * time.Second,     MaxHeaderBytes: 1 << 20,   }   s.ListenAndServe() }

支持Let'sEncrypt证书加密处理HTTPS

下面是一行式的LetsEncrypt HTTPS服务

package main  import (   "log"    "github.com/gin-gonic/autotls"   "github.com/gin-gonic/gin" )  func main() {   r := gin.Default()    // Ping handler   r.GET("/ping", func(c *gin.Context) {     c.String(200, "pong")   })   //一行式LetsEncrypt证书, 处理https   log.Fatal(autotls.Run(r, "example1.com", "example2.com")) }

自定义自动证书管理器autocert manager实例代码:

package main  import (   "log"    "github.com/gin-gonic/autotls"   "github.com/gin-gonic/gin"   "golang.org/x/crypto/acme/autocert" )  func main() {   r := gin.Default()    // Ping handler   r.GET("/ping", func(c *gin.Context) {     c.String(200, "pong")   })    m := autocert.Manager{     Prompt:     autocert.AcceptTOS, //Prompt指定一个回调函数有条件的接受证书机构CA的TOS服务, 使用AcceptTOS总是接受服务条款     HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),  //HostPolicy用于控制指定哪些域名, 管理器将检索新证书     Cache:      autocert.DirCache("/var/www/.cache"),  //缓存证书和其他状态   }    log.Fatal(autotls.RunWithManager(r, &m)) }

详情参考autotls包

使用Gin运行多个服务

可以在主函数中使用协程Goroutine运行多个服务, 每个服务端口不同, 路由分组也不同. 请参考这个问题, 尝试运行以下示例代码:

package main  import (   "log"   "net/http"   "time"    "github.com/gin-gonic/gin"   "golang.org/x/sync/errgroup" )  var (   g errgroup.Group )  func router01() http.Handler {   e := gin.New()   e.Use(gin.Recovery())   e.GET("/", func(c *gin.Context) {     c.JSON(       http.StatusOK,       gin.H{         "code":  http.StatusOK,         "error": "Welcome server 01",       },     )   })    return e }  func router02() http.Handler {   e := gin.New()   e.Use(gin.Recovery())   e.GET("/", func(c *gin.Context) {     c.JSON(       http.StatusOK,       gin.H{         "code":  http.StatusOK,         "error": "Welcome server 02",       },     )   })    return e }  func main() {   server01 := &http.Server{     Addr:         ":8080",     Handler:      router01(),     ReadTimeout:  5 * time.Second,     WriteTimeout: 10 * time.Second,   }    server02 := &http.Server{     Addr:         ":8081",     Handler:      router02(),     ReadTimeout:  5 * time.Second,     WriteTimeout: 10 * time.Second,   }    g.Go(func() error {     err := server01.ListenAndServe()     if err != nil && err != http.ErrServerClosed {       log.Fatal(err)     }     return err   })    g.Go(func() error {     err := server02.ListenAndServe()     if err != nil && err != http.ErrServerClosed {       log.Fatal(err)     }     return err   })    if err := g.Wait(); err != nil {     log.Fatal(err)   } }  /* 模拟访问服务1: curl http://localhost:8080/ {"code":200,"error":"Welcome server 01"}  模拟访问服务2: curl http://localhost:8081/ {"code":200,"error":"Welcome server 02"} */

优雅的关闭和重启服务

有一些方法可以优雅的关闭或者重启服务, 比如不应该中断活动的连接, 需要优雅等待服务完成后才执行关闭或重启. 你可以使用第三方包来实现, 也可以使用内置的包自己实现优雅关闭或重启.

使用第三方包

fvbock/endless 包, 可以实现Golang HTTP/HTTPS服务的零停机和优雅重启(Golang版本至少1.3以上)

我们可以使用fvbock/endless 替代默认的 ListenAndServe方法, 更多详情, 请参考问题#296.

router := gin.Default() router.GET("/", handler) // [...] endless.ListenAndServe(":4242", router)

其他替代包:

  • manners: 一个优雅的Go HTTP服务, 可以优雅的关闭服务.

  • graceful: 优雅的Go包, 能够优雅的关闭一个http.Handler服务

  • grace: 该包为Go服务实现优雅重启, 零停机

手动实现

如果你使用Go1.8或者更高的版本, 你可能不需要使用这些库. 可以考虑使用http.Server的内置方法Shutdown()来优雅关闭服务. 下面的示例描述了基本用法, 更多示例请参考这里

// +build go1.8  package main  import (   "context"   "log"   "net/http"   "os"   "os/signal"   "syscall"   "time"    "github.com/gin-gonic/gin" )  func main() {   router := gin.Default()   router.GET("/", func(c *gin.Context) {     time.Sleep(5 * time.Second)     c.String(http.StatusOK, "Welcome Gin Server")   })    srv := &http.Server{     Addr:    ":8080",     Handler: router,   }    // Initializing the server in a goroutine so that   // it won't block the graceful shutdown handling below   // 用协程初始化一个服务, 它不会阻塞下面的优雅逻辑处理   go func() {     if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {       log.Fatalf("listen: %s\n", err)     }   }()    // Wait for interrupt signal to gracefully shutdown the server with   // a timeout of 5 seconds.   //等待一个操作系统的中断信号, 来优雅的关闭服务   quit := make(chan os.Signal)   // kill (no param) default send syscall.SIGTERM  //kill会发送终止信号   // kill -2 is syscall.SIGINT  //发送强制进程结束信号   // kill -9 is syscall.SIGKILL but can't be catch, so don't need add it  //发送SIGKILL信号给进程   signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)   <-quit //阻塞在这里,直到获取到一个上面的信号   log.Println("Shutting down server...")    // The context is used to inform the server it has 5 seconds to finish   // the request it is currently handling   //这里使用context上下文包, 有5秒钟的处理超时时间   ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)   defer cancel()   if err := srv.Shutdown(ctx); err != nil {  //利用内置Shutdown方法优雅关闭服务     log.Fatal("Server forced to shutdown:", err)   }    log.Println("Server exiting") }

感谢各位的阅读,以上就是"Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结"的内容了,经过本文的学习后,相信大家对Golang GinWeb框架之重定向/自定义中间件/认证/HTTPS支持/优雅重启等知识点总结这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

服务 优雅 中间件 方法 认证 上下 上下文 支持 证书 知识 知识点 信号 链接 参考 处理 框架 问题 面的 阻塞 副本 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 科技互联网产品 网络科技有限互联网 互联网科技公司官网 互联网科技排名 睿民互联网科技 剑昆互联网络科技有限公司临桂 湖南诚度互联网科技有限公司 全球顶尖互联网科技公司 想开互联网科技公司怎么样 中国科技创新与世界互联网大会 互联网在线教育科技创业 华中科技大学互联网的牛人 宇信科技在杭州互联网排第几 新氧科技和美国互联网有关系吗 上海万顺科技互联网有限公司招聘 科技互联网经济论坛 北京军民互联网科技公司 现代科技的标志之一的互联网 如何强化互联网金融科技 株洲百竞科技的互联网营销顾问 国智互联网科技 亿账通互联网科技 佰商互联网科技有限公司 互联网科技公司招聘 云创客互联网科技公司 小米互联网科技园设置 科技与互联网哪个更好 萌小萌互联网科技河南有限公司 互联网科技收购价值 网互联网络科技
0