You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

93 lines
2.1 KiB

package jwt
import (
"context"
"git.diulo.com/mogfee/kit/middleware"
)
type JwtOption func(o *options)
func WithJwtKey(jwtKey string) JwtOption {
return func(o *options) {
o.jwtKey = jwtKey
}
}
func WithFromKey(fromKey string) JwtOption {
return func(o *options) {
o.fromKey = fromKey
}
}
func WithValidate(val JwtValidate) JwtOption {
return func(o *options) {
o.validate = val
}
}
type options struct {
jwtKey string
fromKey string //cookie:token header:key
validate JwtValidate
}
type JwtValidate interface {
//GetToken 获取token
GetToken(ctx context.Context, key string) (tokenStr string)
//ParseToken 解析token获取用户信息
ParseToken(ctx context.Context, key string, token string) (*UserInfo, error)
//Validate 校验权限
Validate(ctx context.Context, permission string, permissions []string) error
}
func JWT(opts ...JwtOption) middleware.Middleware {
var cfg = &options{
jwtKey: "JssLx22bjQwnyqby",
fromKey: "header:token",
validate: &JwtDefault{},
}
for _, o := range opts {
o(cfg)
}
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, a any) (any, error) {
//1. 解析token
//2. 获取用户信息
//3. 校验权限
//4. 设置ctx
authKey := FromAuthKeyContext(ctx)
needAuth := FromNeedAuthContext(ctx)
// 解析token
tokenStr := cfg.validate.GetToken(ctx, cfg.fromKey)
if tokenStr == "" && needAuth {
return nil, errorx.Unauthorized("NO_TOKEN", "")
}
if tokenStr != "" {
if err := func() error {
userInfo, err := cfg.validate.ParseToken(ctx, cfg.jwtKey, tokenStr)
if err != nil {
return err
}
if needAuth && userInfo.UserId == "" {
return errorx.Unauthorized("TOKEN_BAD", "")
}
if authKey != "" {
if err = cfg.validate.Validate(ctx, authKey, userInfo.Permissions); err != nil {
return err
}
}
if userInfo.UserId != "" {
ctx = SetUserContext(ctx, userInfo)
}
return nil
}(); err != nil {
if needAuth {
return nil, err
}
}
}
return handler(ctx, a)
}
}
}