golang 中间件的实现本质:

写一个func,接受handler并且返回handler

把私货写在func里面,从而实现把你要写的操作执行了之后,再把原有的流程进行下去

一个好的中间件有一个责任就是可插拔并且自足。

例子:

package main

import (

"fmt"

"github.com/devfeel/dotweb"

)

func main() {

app := dotweb.New()

// App注册中间件

app.Use(NewSessionAuth())

// 开启SESSION

app.HttpServer.SetEnabledSession(true)

// 设置路由 输出字符串 Hello Dotweb

app.HttpServer.GET("/", func(ctx dotweb.Context) error {

method := ctx.Request().Method

return ctx.WriteString("Hello Dotweb\n" + "Method:" + method)

})

//开启服务 端口号

fmt.Println("dotweb.StartServer => 8080")

err := app.StartServer(8080)

fmt.Println("dotweb.StartServer error => ", err)

}

// SessionAuth 结构体

type SessionAuth struct {

dotweb.BaseMiddlware

}

// Handle 处理程序

func (m *SessionAuth) Handle(ctx dotweb.Context) error {

fmt.Println("SessionID = ", ctx.SessionID(), " RequestURI = ", ctx.Request().RequestURI)

return m.Next(ctx)

}

// NewSessionAuth New

func NewSessionAuth() *SessionAuth {

sAuth := new(SessionAuth)

return sAu

}

Handle是什么时候被调用的?

我们看看BaseMiddlWare的源码:

// BaseMiddleware is the base struct, user defined middleware should extend this

type BaseMiddleware struct {

next Middleware

excludeRouters map[string]struct{}

}

func (bm *BaseMiddleware) SetNext(m Middleware) {

bm.next = m

}

func (bm *BaseMiddleware) Next(ctx Context) error {

httpCtx := ctx.(*HttpContext)

if httpCtx.middlewareStep == "" {

httpCtx.middlewareStep = middleware_App

}

if bm.next == nil {

if httpCtx.middlewareStep == middleware_App {

httpCtx.middlewareStep = middleware_Group

if len(httpCtx.RouterNode().GroupMiddlewares()) > 0 {

return httpCtx.RouterNode().GroupMiddlewares()[0].Handle(ctx)

}

}

​​​​​​​

if httpCtx.middlewareStep == middleware_Group {

httpCtx.middlewareStep = middleware_Router

if len(httpCtx.RouterNode().Middlewares()) > 0 {

return httpCtx.RouterNode().Middlewares()[0].Handle(ctx)

}

}

if httpCtx.middlewareStep == middleware_Router {

return httpCtx.Handler()(ctx)

}

} else {

// check exclude config

if ctx.RouterNode().Node().hasExcludeMiddleware && bm.next.HasExclude() {

if bm.next.ExistsExcludeRouter(ctx.RouterNode().Node().fullPath) {

return bm.next.Next(ctx)

}

}

return bm.next.Handle(ctx)

}

return n

}

通过这个代码我们大概能看出:

BaseMiddleware其实是一个链表的node

中间件组成了一个链表,并且有不同的类型

有group中间件和普通中间件

根据当前ctx所处的处理步骤决定调用哪一个中间件

最后调用ctx的handler

自定义的middleware要继承 BaseMiddleware

并且实现handle

func (asm *ApiSignMiddleware) Handle(ctx dotweb.Context) error {

if sign := ctx.Request().QueryHeader("Sign"); len(sign) <= 0 {

return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})

} else {

uri := ctx.Request().RequestURI

if index := strings.Index(uri, "?"); index != -1 {

uri = uri[:index]

}

if ok := checkSign(sign, uri); !ok {

return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})

}

return asm.Next(ctx)

}

}

这样就可以对传进来的Contex进行解析

分析一下blogserver里面用到的middleware:

CrosMiddleware

func (cm *CrosMiddleware) Handle(ctx dotweb.Context) error {

if strings.Contains(ctx.Request().RequestURI, "v1") && ctx.Request().Method != "OPTIONS" {

if sign := ctx.Request().QueryHeader("Sign"); len(sign) <= 0 {

return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})

} else {

uri := ctx.Request().RequestURI

if index := strings.Index(uri, "?"); index != -1 {

uri = uri[:index]

}

if ok := checkSign(sign, uri); !ok {

return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})

}

return cm.Next(ctx)

}

}

return cm.Next(ctx)

}

CrosMiddleware 对uri的非参数部分调用checkSign

//验证签名 (requestUri(不含query)+secret)

func checkSign(sign, uri string) bool {

result := utils.Md5(uri + config.Config().SecretKey)

return result == sign

}

传过来得header里面得sign值应该跟 uri + 配置文件里面的 SecretKey 取md5 一致

文章来源: blog.csdn.net,作者:只要你在,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/icebergliu1234/article/details/110437090

golang做php的中间件,Golang 之 中间件相关推荐

  1. opentracing php,详解GoLang实现基于gin+jaeger的opentracing中间件

    下面由golang教程栏目给大家介绍GoLang实现基于gin+jaeger的opentracing中间件的方法,希望对需要的朋友有所帮助! 完整源码:https://github.com/why44 ...

  2. golang游戏服务器项目,基于Golang的游戏服务器框架cellnet开发日记(一)

    启程的故事 使用Golang写服务器是一件非常幸福的事情. 不用长时间的等待编译, 零依赖部署. 开发效率高, 多出的时间陪陪家人, 看书充充电多好. 所以Golang就像是手机界的苹果, 从发布后, ...

  3. Spring中间件 - 什么是中间件

    一.前言 在互联网应用开发初期,所有用于支撑系统建设的,框架结构.基础工具.业务逻辑.功能服务包括页面展示等,都是在一个系统中开发完成,最终也只是把系统和数据库部署在同一台服务器上. 但随着互联网应用 ...

  4. PHP中间件 middleware,middleware 中间件详解

    如果感觉这篇文章有用请点个赞,让我知道自己的努力不白费!!! 中间件是请求必经之处,所以此处能对请求的数据做一系列处理,相当于过滤器.例如跨域请求,验证会员是否登录跳转至登录页,前后端分离数据类型不一 ...

  5. 后盾网lavarel视频项目---lavarel中间件(使用中间件拦截没登录的用户)

    后盾网lavarel视频项目---lavarel中间件(使用中间件拦截没登录的用户) 一.总结 一句话总结: 1.中间件中验证用户是否登录:if(!Auth::guard('admin')->c ...

  6. 【golang】从源代码编译golang编译器

    文章目录 系统信息 下载并编译go1.4用作bootstrap编译器 下载golang源代码 编译最新的golang 检查golang编译版本信息 编译一个简单的go程序 系统信息 tsu5@hhvm ...

  7. golang go语言_Go(Golang)编程语言

    golang go语言 Go (or golang) is a programming language created at Google in 2007 by Robert Griesemer, ...

  8. 什么是中间件?常见中间件有哪些?

    文章目录 中间件是什么 为什么使用中间件 常见的中间件有哪些 中间件是什么 中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源.中间件位于客户机/ 服务器的操作系 ...

  9. Java中间件(1)--分布式系统中间件从入门到精通(五)

    上篇文章说了,当业务数据量大的时候,可以考虑业务和数据分离,当还解决不了的时候,可以考虑把数据库读写分离,缓存,还可以考虑把表垂直拆分,水平拆分. 大型网站架构(2)--分布式系统&中间件从入 ...

  10. go 基准测试 找不到函数_基于Golang做测试

    本文在实习期间完成并完善,无任何公司机密,仅做语言交流学习之用. 持续更新. 1.Golang的单元测试 Go语言提供了丰富的单测功能.在Go中,我们通常认为函数是最小的可执行单元.本例中使用两个简单 ...

最新文章

  1. BZOJ3139/BZOJ1306 HNOI2013比赛/CQOI2009循环赛(搜索)
  2. BIEE 目录迁移(文件夹)方式
  3. ArrayList和LinkedList使用不当,性能差距会如此之大!
  4. 基于微服务架构、运行于容器中的.NET Core示例应用eShopOnContainers
  5. 《程序员面试宝典》精华 编程语言部分
  6. 中教云教师备课云平台获北京市新技术新产品(服务)认定
  7. Python+OpenCV:理解K-Means聚类(K-Means Clustering)
  8. 计算机必懂的54个英文单词和缩写
  9. NYOJ759 你知道这个规律吗
  10. 解锁lintcode数字图像识别
  11. 前端学习分为几个阶段,你属于哪个阶段?
  12. Android混淆规则
  13. w ndows 10画图,如何在Windows 10中打开和使用画图
  14. 阿里云ddns过程记录
  15. 校友厅——只有一层的“校友楼”
  16. 模型转换:pth转onnx
  17. 如何下载 Chrome 应用商店的 .crx 文件
  18. python内建方法
  19. 移动通信第三章,组网技术基础
  20. 【配电网重构】基于粒子群算法实现最小化功率损耗的配电网重构附matlab代码

热门文章

  1. java之等差素数的求法
  2. 2小时完成的第一个副业单子:Python修正excel表格数据
  3. 使用mysql解决Excel换行统计问题
  4. 简单扑克牌游戏C语言,【算法】C语言实现简易的扑克牌游戏
  5. 编程大佬行为准则:一杯茶一包烟,一行代码写一天
  6. 企业做好绩效管理的四种方法
  7. JavaEE | 基本类型包装类
  8. “数据中台”在安防行业的应用与发展
  9. 小程序实现书籍翻页效果
  10. 2019-01-21-mqtt-mosquitto-启动Unable to load CA certificates