Go-zero:JWT鉴权方式

1.简述

用于记录在go-zero的后端项目中如何添加jwt中间件鉴权

2.流程

配置api.yaml

go 复制代码
Auth:
  AccessSecret: "secret_key"
  AccessExpire: 604800

config中添加Auth结构体

go 复制代码
Auth struct {
		AccessSecret string
		AccessExpire int64
}

types定义jwt token的自定义数据结构,这里以用户登录信息的UserClaims做例子,在types中新建userclaims.go文件

go 复制代码
type UserClaims struct {
	UserUID int64  `json:"user_uid"`
	Role    string `json:"role"`
	jwt.RegisteredClaims
}

中间件方法:在middleware文件夹下建立jwtmiddleware.go用来储存创立和返回jwt中间件
1.jwt中间件结构体,包含一个secret字段用来实现jwt验签

go 复制代码
// jwt中间件结构体,包含一个secret字段,用于jwt验签
type JWTMiddleware struct {
	Secret string
}

2.创建jwtmiddleware的实例

go 复制代码
// 工厂方法,用于创建和返回JWTMiddleware实力
func NewJWTMiddleware(secret string) *JWTMiddleware {
	return &JWTMiddleware{Secret: secret}
}

3.中间件签名,接收一个函数handler,获取请求头中的token并解析,然后送入另一个handler

go 复制代码
// 中间件签名,接受一个下一个处理的函数,返回另一个处理函数
func (m *JWTMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		//获取请求头中的token
		tokenStr := r.Header.Get("Authorization")
		if tokenStr == "" {
			http.Error(w, "Missing token", http.StatusUnauthorized)
			return
		}

		//解析token并绑定自定义结构体UserClaims
		token, err := jwt.ParseWithClaims(tokenStr, &types.UserClaims{}, func(token *jwt.Token) (interface{}, error) {
			return []byte(m.Secret), nil
		})

		//检查是否有效
		if err != nil || !token.Valid {
			http.Error(w, "Invalid token", http.StatusUnauthorized)
			return
		}

		// 将解析结果保存进 context
		if claims, ok := token.Claims.(*types.UserClaims); ok {
			ctx := context.WithValue(r.Context(), "user_uid", claims.UserUID)
			ctx = context.WithValue(ctx, "role", claims.Role)
			r = r.WithContext(ctx)
		}

		next(w, r)
	}
}

servicecontext中注册并初始化jwt中间件

go 复制代码
type ServiceContext struct {
	Config        config.Config
	DB            *gorm.DB
	UserModel     model.IUserModel
	JWTMiddleware *middleware.JWTMiddleware
}

func NewServiceContext(c config.Config) *ServiceContext {

	db, err := gorm.Open(mysql.Open(c.Mysql.DataSource), &gorm.Config{})
	if err != nil {
		panic("connect failed : " + err.Error())
	}
	_ = db.AutoMigrate(
		&model.User{},
		&model.Post{},
		&model.Comment{},
		&model.Like{},
		&model.Report{},
		&model.Section{},
		&model.SearchModel{},
		&model.InstallationStatus{})

	return &ServiceContext{
		Config:        c,
		DB:            db,
		JWTMiddleware: middleware.NewJWTMiddleware(c.Auth.AccessSecret),
	}

}

routes中给要使用jwt的api进行包装(这里还没写需要用的api,大概语法如下)

go 复制代码
//初始化中间件
jwtMW := middleware.NewJWTMiddleware(secret_key)
//包装需要用的api
server.AddRoutes(
		[]rest.Route{
			{
				Method:  http.MethodPost,
				Path:    "/api/user_info",
				Handler: jwtMW.Handle(GetUserInfo(user_uid)),
			},
		},
	)
相关推荐
头发那是一根不剩了5 分钟前
Spring Boot 多数据源切换:AbstractRoutingDataSource
数据库·spring boot·后端
witton16 分钟前
Go语言网络游戏服务器模块化编程
服务器·开发语言·游戏·golang·origin·模块化·耦合
叹一曲当时只道是寻常19 分钟前
Softhub软件下载站实战开发(十六):仪表盘前端设计与实现
前端·golang
小杰来搬砖32 分钟前
讲解instanceof 用法
后端
城里的月光38 分钟前
从900 MB到450 MB:生产中SpringBoot的JVM内存调优技巧
后端
枯萎穿心攻击1 小时前
ECS由浅入深第三节:进阶?System 的行为与复杂交互模式
开发语言·unity·c#·游戏引擎
Jerry Lau1 小时前
go go go 出发咯 - go web开发入门系列(一) helloworld
开发语言·前端·golang
nananaij1 小时前
【Python基础入门 re模块实现正则表达式操作】
开发语言·python·正则表达式
Pedantic1 小时前
为什么 Swift 字符串不能用 `myString[3]` 随便取字符?
前端·后端
Micro麦可乐1 小时前
Java常用加密算法详解与实战代码 - 附可直接运行的测试示例
java·开发语言·加密算法·aes加解密·rsa加解密·hash算法