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.

88 lines
2.0 KiB

2 years ago
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
}
}
2 years ago
func WithFromKey(fromKey string) JwtOption {
2 years ago
return func(o *options) {
2 years ago
o.fromKey = fromKey
2 years ago
}
}
2 years ago
func WithValidate(val JwtValidate) JwtOption {
2 years ago
return func(o *options) {
2 years ago
o.validate = val
2 years ago
}
}
2 years ago
type options struct {
2 years ago
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
2 years ago
}
func JWT(opts ...JwtOption) middleware.Middleware {
var cfg = &options{
2 years ago
jwtKey: "JssLx22bjQwnyqby",
fromKey: "header:token",
2 years ago
validate: &JwtDefault{},
2 years ago
}
for _, o := range opts {
o(cfg)
}
return func(handler middleware.Handler) middleware.Handler {
return func(ctx context.Context, a any) (any, error) {
2 years ago
//1. 解析token
//2. 获取用户信息
//3. 校验权限
//4. 设置ctx
2 years ago
authKey := FromAuthKeyContext(ctx)
needAuth := FromNeedAuthContext(ctx)
2 years ago
2 years ago
// 解析token
tokenStr := cfg.validate.GetToken(ctx, cfg.fromKey)
if tokenStr == "" && needAuth {
return nil, errors.Unauthorized("NO_TOKEN", "")
}
2 years ago
if tokenStr != "" {
userInfo, err := cfg.validate.ParseToken(ctx, cfg.jwtKey, tokenStr)
if err != nil {
2 years ago
return nil, err
2 years ago
}
2 years ago
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)
}
2 years ago
}
2 years ago
return handler(ctx, a)
}
}
}