基于jwt(认证)和casbin(鉴权)。
生成jwt部分参考jwt的介绍以及直接看Kratos的源码。
鉴权部分参考官方示例。
一般可以把鉴权单独部署服务
主要流程如下:
登录部分一般要校验登录密码(这里没有校验)
通过用户名找到对应的角色(保存在配置文件或者数据库中)
生成JWT
func (s *AdminService) Login(_ context.Context, req *v1.LoginReq) (*v1.User, error) {
fmt.Println("Login", req.UserName, req.Password)
var id uint64 = 10
var email = "hello@kratos.com"
var roles []string
switch req.UserName {
case "admin":
roles = append(roles, "ROLE_ADMIN")
case "moderator":
roles = append(roles, "ROLE_MODERATOR")
}
var securityUser myAuthz.SecurityUser
securityUser.AuthorityId = req.GetUserName()
token := securityUser.CreateAccessJwtToken([]byte(s.auth.GetApiKey()))
return &v1.User{
Id: &id,
UserName: &req.UserName,
Token: &token,
Email: &email,
Roles: roles,
}, nil
}
校验部分直接以中间件的形式放在服务启动的地方
func NewMiddleware(ac *conf.Auth, logger log.Logger) http.ServerOption {
m, _ := model.NewModelFromFile("../../configs/authz/authz_model.conf")
a := fileAdapter.NewAdapter("../../configs/authz/authz_policy.csv")
return http.Middleware(
recovery.Recovery(),
tracing.Server(),
logging.Server(logger),
selector.Server(
jwt.Server(
func(token *jwtV4.Token) (interface{}, error) {
return []byte(ac.ApiKey), nil
},
jwt.WithSigningMethod(jwtV4.SigningMethodHS256),
), // Server检查token和解析出的信息,并写入到ctx中。注意这个ac.ApiKey要与签发(本例中是登录)的地方一致
casbinM.Server(
casbinM.WithCasbinModel(m),
casbinM.WithCasbinPolicy(a),
casbinM.WithSecurityUserCreator(myAuthz.NewSecurityUser),
),// 加载casbin配置
).
Match(NewWhiteListMatcher()).Build(),
)
}
// NewWhiteListMatcher 对操作接口的白名单配置
其他参考,流程简要说明:
- 前端发送登陆请求
- 登陆请求处理
2.1 验证用户名密码
2.2 securityUser.CreateAccessJwtToken生成Jwt的Token
2.3 返回token给前端 - 其他正常的请求
3.1 Jwt中间件进行令牌认证信息校验
3.2 Casbin中间件解析Jwt中间件的Payload信息,根据用户信息以及操作名进行权鉴。