showliuzp 2025-09-23 18:46 采纳率: 84.3%
浏览 7
已结题

golang中间件传递参数


type TokenHandler func(req interface{}, token *string) (interface{}, error)

//工会管理Token内容中间件处理
func WithTokenAccountValidation(handler TokenHandler) TokenHandler {
    return func(req interface{}, token *string) (interface{}, error) {
        token_detail, err := tools.ParseToken(token)
        if err != nil {
            return nil, err
        }

        fmt.Printf("详情:%+v\n",token_detail)
        return handler(req, token)
    }
}


func OperatorList(r *http.Request)(resp interface{}, err error){
    authorization := (*r).Header.Get(types.HEADER_AUTH)
    var req = new(iapi.OperatorListReq)
    if resp,err = ParseReq(r,&req,"获取操作者列表,前端参数错误",log_tag_operator);err != nil{
                return
    }

    PageSetComm(&(req.PageReq))

    resp,err = WithTokenAccountValidation(operator_obj.ListWrapper)(req,&authorization)

    return
}

func (o *Operator) ListWrapper(req interface{}, token *string) (interface{}, error) {
    operatorReq, ok := req.(*iapi.OperatorListReq)
    if !ok {
        return nil, fmt.Errorf("类型转换错误")
    }

    return o.List(operatorReq, token)
}


我定义了一个如上的中间件,token_detail我想作为参数传入handler,但不想token也作为参数传入handler,应该怎么做?
  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-09-23 18:48
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    你目前的中间件设计中,TokenHandler 的签名是:

    type TokenHandler func(req interface{}, token *string) (interface{}, error)
    

    这意味着 handler 必须接收 reqtoken 两个参数。如果你希望 token_detail 作为参数传递给 handler,而 不传递原始的 token 字符串,你需要对中间件和 handler 的签名进行调整。


    ✅ 解决方案

    1. 修改 TokenHandler 的定义

    将原来的 TokenHandler 改为接收 token_detail 而不是原始 token 字符串:

    type TokenHandler func(req interface{}, tokenDetail *TokenDetail) (interface{}, error)
    

    其中 TokenDetail 是你从 tools.ParseToken(token) 返回的结构体类型(例如:*UserToken*AuthPayload)。


    2. 修改中间件函数 WithTokenAccountValidation

    在中间件中解析 token 得到 token_detail,然后将其传入 handler,而不是原始的 token 字符串。

    // 假设 TokenDetail 是你解析后的结构体类型
    type TokenDetail struct {
        UserID   string
        Username string
        // 其他字段...
    }
    
    func WithTokenAccountValidation(handler TokenHandler) TokenHandler {
        return func(req interface{}, token *string) (interface{}, error) {
            tokenDetail, err := tools.ParseToken(token)
            if err != nil {
                return nil, err
            }
    
            fmt.Printf("详情:%+v\n", tokenDetail)
    
            // 将 tokenDetail 传递给 handler,而不是原始 token
            return handler(req, tokenDetail)
        }
    }
    

    3. 修改 ListWrapper 函数的签名

    确保 ListWrapper 接收的是 tokenDetail 而不是 token

    func (o *Operator) ListWrapper(req interface{}, tokenDetail *TokenDetail) (interface{}, error) {
        operatorReq, ok := req.(*iapi.OperatorListReq)
        if !ok {
            return nil, fmt.Errorf("类型转换错误")
        }
    
        return o.List(operatorReq, tokenDetail)
    }
    

    4. 修改 OperatorList 函数中的调用方式

    在调用中间件时,确保只传递 authorization(即 *string),不需要修改调用逻辑,因为中间件会自动处理 tokentokenDetail 的转换。

    resp, err = WithTokenAccountValidation(o.ListWrapper)(req, &authorization)
    

    ✅ 总结

    | 步骤 | 修改内容 | |------|----------| | 1 | 定义新的 TokenHandler 类型,接受 tokenDetail | | 2 | 修改中间件 WithTokenAccountValidation,解析 token 得到 tokenDetail 并传递给 handler | | 3 | 修改 ListWrapper 函数,使其接收 tokenDetail 而不是 token | | 4 | 确保调用逻辑不变,中间件会自动处理参数转换 |


    📌 示例代码(完整修改后)

    // 定义 TokenDetail 结构体
    type TokenDetail struct {
        UserID   string
        Username string
        // ...其他字段
    }
    
    // 新的 TokenHandler 类型
    type TokenHandler func(req interface{}, tokenDetail *TokenDetail) (interface{}, error)
    
    // 中间件函数
    func WithTokenAccountValidation(handler TokenHandler) TokenHandler {
        return func(req interface{}, token *string) (interface{}, error) {
            tokenDetail, err := tools.ParseToken(token)
            if err != nil {
                return nil, err
            }
    
            fmt.Printf("详情:%+v\n", tokenDetail)
    
            return handler(req, tokenDetail)
        }
    }
    
    // ListWrapper 接收 tokenDetail
    func (o *Operator) ListWrapper(req interface{}, tokenDetail *TokenDetail) (interface{}, error) {
        operatorReq, ok := req.(*iapi.OperatorListReq)
        if !ok {
            return nil, fmt.Errorf("类型转换错误")
        }
    
        return o.List(operatorReq, tokenDetail)
    }
    
    // OperatorList 函数
    func OperatorList(r *http.Request) (resp interface{}, err error) {
        authorization := (*r).Header.Get(types.HEADER_AUTH)
        var req = new(iapi.OperatorListReq)
        if resp, err = ParseReq(r, &req, "获取操作者列表,前端参数错误", log_tag_operator); err != nil {
            return
        }
    
        PageSetComm(&(req.PageReq))
    
        resp, err = WithTokenAccountValidation(o.ListWrapper)(req, &authorization)
    
        return
    }
    

    如有更多关于 tools.ParseToken 的返回结构或具体业务逻辑,也可以进一步优化。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 10月5日
  • 已采纳回答 9月27日
  • 创建了问题 9月23日