KeyAuth

Hertz 提供了 keyauth 扩展用于帮助用户实现 token 鉴权。

Hertz 提供了 keyauth 扩展用于帮助用户实现 token 鉴权。 keyauth 扩展的实现参考了 FiberEcho 的实现。

安装

go get github.com/hertz-contrib/keyauth

示例代码

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
	"github.com/hertz-contrib/keyauth"
)

func main() {
	h := server.Default()
	h.Use(keyauth.New(
		keyauth.WithContextKey("token"),
		keyauth.WithKeyLookUp("query:token", ""),
	))
	h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		value, _ := ctx.Get("token")
		ctx.JSON(consts.StatusOK, utils.H{"ping": value})
	})
	h.Spin()
}

配置

WithFilter

keyauth 扩展提供了 WithFilter 用于帮助用户设置自定义过滤逻辑用于跳过 keyauth 扩展,默认为 nil,不跳过。

Filter 函数签名如下:

type KeyAuthFilterHandler func(c context.Context, ctx *app.RequestContext) bool

示例代码:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
	"github.com/hertz-contrib/keyauth"
)

func main() {
	h := server.Default()
	h.Use(keyauth.New(
		keyauth.WithFilter(func(c context.Context, ctx *app.RequestContext) bool {
			return string(ctx.GetHeader("admin")) == "test"
		}),
	))
	h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		value, _ := ctx.Get("token")
		ctx.JSON(consts.StatusOK, utils.H{"ping": value})
	})
	h.Spin()
}

WithValidator

keyauth 扩展提供了 WithValidator 用于帮助用户设置自定义的校验逻辑用于 token 校验,默认返回 truenil

Validator 函数签名如下:

type KeyAuthValidatorHandler func(context.Context, *app.RequestContext, string) (bool, error)

示例代码:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
	"github.com/hertz-contrib/keyauth"
)

func main() {
	h := server.Default()
	h.Use(keyauth.New(
		keyauth.WithValidator(func(ctx context.Context, requestContext *app.RequestContext, s string) (bool, error) {
			if s == "test_admin" {
				return true, nil
			}
			return false, nil
		}),
	))
	h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		value, _ := ctx.Get("token")
		ctx.JSON(consts.StatusOK, utils.H{"ping": value})
	})
	h.Spin()
}

WithSuccessHandler

keyauth 扩展提供了 WithSuccessHandler 用于帮助用户设置校验 token 通过的自定义处理逻辑。

示例代码:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
	"github.com/hertz-contrib/keyauth"
)

func main() {
	h := server.Default()
	h.Use(keyauth.New(
		keyauth.WithSuccessHandler(func(c context.Context, ctx *app.RequestContext) {
			ctx.Next(c)
		}),
	))
	h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		value, _ := ctx.Get("token")
		ctx.JSON(consts.StatusOK, utils.H{"ping": value})
	})
	h.Spin()
}

WithErrorHandler

keyauth 扩展提供了 WithErrorHandler 用于帮助用户设置校验 token 失败的自定义处理逻辑。

ErrorHandler 函数签名如下:

type KeyAuthErrorHandler func(context.Context, *app.RequestContext, error)

默认处理逻辑如下:

func errHandler(c context.Context, ctx *app.RequestContext, err error) {
	if err == ErrMissingOrMalformedAPIKey {
		ctx.AbortWithMsg(err.Error(), http.StatusBadRequest)
		return
	}
	ctx.AbortWithMsg(err.Error(), http.StatusUnauthorized)
}

WithKeyLookUp

keyauth 扩展提供了 WithKeyLookUp 帮助用户设置 keyLookup

keyLookup 用于从 source(支持的 source 包括 cookieheaderparamqueryform) 中提取 token

格式为 <source>:<token_name>,默认值为:header:Authorization

示例代码:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
	"github.com/hertz-contrib/keyauth"
)

func main() {
	h := server.Default()
	h.Use(keyauth.New(
		keyauth.WithKeyLookUp("header:token", "Bearer"),
		))
	h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		value, _ := ctx.Get("token")
		ctx.JSON(consts.StatusOK, utils.H{"ping": value})
	})
	h.Spin()
}

WithContextKey

keyauth 扩展提供了 WithContextKey 用于帮助用户设置存储在请求上下文的 token 对应的 key

示例代码:

package main

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/app/server"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
	"github.com/hertz-contrib/keyauth"
)

func main() {
	h := server.Default()
	h.Use(keyauth.New(
		keyauth.WithContextKey("token"),
	))
	h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
		value, _ := ctx.Get("token")
		ctx.JSON(consts.StatusOK, utils.H{"ping": value})
	})
	h.Spin()
}

最后修改 January 18, 2024 : Upload volo blog (#936) (1fc8abb)