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.
94 lines
2.1 KiB
94 lines
2.1 KiB
package jwt |
|
|
|
import ( |
|
"context" |
|
"git.diulo.com/mogfee/kit/errors" |
|
"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, errors.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 errors.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) |
|
} |
|
} |
|
}
|
|
|