使用kratos框架集成jwt认证
问题背景:网络鉴权在web开发中最常见不过了,最近在使用go kratos框架写项目的时候需要用到jwt,查阅资料后自己动手实现了简单的鉴权,在这里记录一下实现步骤,直接上代码。
- 定义jwt签发函数
这部分我是参考了李文周老师的博客
博客地址:https://www.liwenzhou.com/posts/Go/json-web-token/
// MySigningKey 用于签名的字符串
var MySigningKey = []byte("mysecret")
const TokenExpireDuration = time.Hour * 24
type CustomClaims struct {
// 可根据需要自行添加字段
Username string `json:"username"`
jwt.RegisteredClaims // 内嵌标准的声明
}
// GenRegisteredClaims 使用默认声明创建jwt
func GenRegisteredClaims(username string) (string, error) {
// 创建 Claims
claims := CustomClaims{
username,
jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(TokenExpireDuration)),
Issuer: "my-project",
},
}
// 生成token对象
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 生成签名字符串
return token.SignedString(MySigningKey)
}
- 在kratos框架中完成token认证中间件
这部分是参考了kratos官方文档
参考地址:https://go-kratos.dev/docs/component/middleware/overview
// server/http.go
options := []jwt.Option{
jwt.WithClaims(func() jwtv4.Claims {
return &utils.CustomClaims{}
}),
}
testKey := utils.MySigningKey
var opts = []http.ServerOption{
http.Middleware(
recovery.Recovery(),
// 选择器中间件,只对支付接口生效
selector.Server(
// 认证中间件,传入func和options
jwt.Server(
func(token *jwtv4.Token) (interface{}, error) {
return []byte(testKey), nil
}, options...,
)).Path("/helloworld.v1.Greeter/Pay").Build(),
),
}
// grpc部分与http认证类似,此处不再赘述
- 以上步骤成功实现了签发token和验证token,最后一部是把从token中解析的部分放到之后的请求上下文中
// 其实这一部分通过看源码就可以知道,框架已经帮我们处理好了,我们要做的就只是从context中把claim拿出来,通过断言判断类型就可以了。以下只是简单实现
claimsInterface, ok := jwt.FromContext(ctx)
if !ok {
return &v1.PayReply{Message: "no ", OrderId: in.OrderId}, nil
}
claims, ok := claimsInterface.(*utils.CustomClaims)
fmt.Println(claims)
if !ok {
return &v1.PayReply{Message: "no ", OrderId: in.OrderId}, nil
}
if claims.Username == "admin" {
return &v1.PayReply{Message: claims.Username, OrderId: in.OrderId}, nil
}
return &v1.PayReply{Message: "no ", OrderId: in.OrderId}, nil
通过以上简单步骤就可以在kratos框架中实现简单的jwt认证,web请求访问对应路由时,请求头应携带相应的token,否则会被拦截。
浙公网安备 33010602011771号