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.
 
 

87 lines
2.0 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 != "" {
userInfo, err := cfg.validate.ParseToken(ctx, cfg.jwtKey, tokenStr)
if err != nil {
return nil, err
}
if needAuth && userInfo.UserId == 0 {
return nil, errors.Unauthorized("TOKEN_BAD", "")
}
if authKey != "" {
if err := cfg.validate.Validate(ctx, authKey, userInfo.Permissions); err != nil {
return nil, err
}
}
if userInfo.UserId > 0 {
ctx = SetUserContext(ctx, userInfo)
}
}
return handler(ctx, a)
}
}
}