GO电商项目JMT与gtoken

什么是JMT?什么是gtoken?

JWT(JSON Web Token)和gtoken都是用于用户认证和授权的技术;token 是一串字符串,通常因为作为鉴权凭据。

二者区别

1.实现方式: JWT是一种标准和规范,有多种语言的实现;gtoken是GoFrame框架的特定组件,专为GoFrame设计

2.存储方式: JWT通常是无状态的,服务器不需要存储token;gtoken支持将token存储在内存或Redis中,便于管理和控制

3.功能扩展: gtoken提供了更多GoFrame生态的便捷功能,如多端登录控制、自动续期等;JWT更加轻量,但需要自己实现一些额外功能 4.使用场景: JWT适合跨服务、跨平台的认证场景;gtoken更适合GoFrame框架内的项目,提供更便捷的集成体验

在项目的应用

gtoken是一个基于GoFrame框架的令牌管理和身份验证中间件,它是用于GoFrame框架的一个第三方扩展包,由goflyfox开发,主要用于处理用户登录认证和授权。从代码中可以看到,项目(goframe-shop-v2)使用了github.com/goflyfox/gtoken v1.5.7这个版本。简单来说,gtoken就像是一个门卫,负责检查访问系统的人是否有合法的"通行证"(token)。

1. 分离前后台认证系统

项目中使用了两套gtoken认证系统:

  • 管理后台认证:通过StartBackendGToken()函数初始化,用于管理员登录和后台管理
  • 前台用户认证:通过StartFrontendGToken()函数初始化,用于普通用户登录和前台操作

2. 登录验证流程

gtoken的登录验证流程如下:

(1)登录前验证:

  • 后台使用loginFunc函数

loginFunc 用于处理登录请求,从请求中获取用户名和密码,并进行简单的非空校验。如果验证不通过,则立即返回错误响应; 上下文(ctx)的使用:context.TODO() 是一个占位,提示后续可能需要根据业务需求换成合适的上下文;退出机制:当用户名或密码缺失时,通过返回 JSON 错误信息并调用 r.ExitAll() 终止请求中的其他处理工作。 TODO 注释:是一个常见的编程标记,用于提示开发者代码中未完成或有待改进的部分。在其它代码位置,它提醒团队或未来的你需要去掉或优化全局校验逻辑。

  • 前台使用loginFuncFrontend函数

这两个函数负责验证用户名和密码,查询数据库确认用户身份

(2)登录成功后的处理:

  • 后台使用loginAfterFunc函数
func 复制代码
	if !respData.Success() {
		respData.Code = 0
		r.Response.WriteJson(respData)
		return
	} else {
		respData.Code = 1
		//获得登录用户id
		userKey := respData.GetString("userKey")
		adminId := gstr.StrEx(userKey, consts.GTokenAdminPrefix)
		//根据id获得登录用户其他信息
		adminInfo := entity.AdminInfo{}
		err := dao.AdminInfo.Ctx(context.TODO()).WherePri(adminId).Scan(&adminInfo)
		if err != nil {
			return
		}
		//通过角色查询权限
		//先通过角色查询权限id
		var rolePermissionInfos []entity.RolePermissionInfo
		err = dao.RolePermissionInfo.Ctx(context.TODO()).WhereIn(dao.RolePermissionInfo.Columns().RoleId, g.Slice{adminInfo.RoleIds}).Scan(&rolePermissionInfos)
		if err != nil {
			return
		}
		permissionIds := g.Slice{}
		for _, info := range rolePermissionInfos {
			permissionIds = append(permissionIds, info.PermissionId)
		}

		var permissions []entity.PermissionInfo
		err = dao.PermissionInfo.Ctx(context.TODO()).WhereIn(dao.PermissionInfo.Columns().Id, permissionIds).Scan(&permissions)
		if err != nil {
			return
		}
		data := &backend.LoginRes{
			Type:        consts.TokenType,
			Token:       respData.GetString("token"),
			ExpireIn:    consts.GTokenExpireIn, //单位秒,
			IsAdmin:     adminInfo.IsAdmin,
			RoleIds:     adminInfo.RoleIds,
			Permissions: permissions,
		}
		response.JsonExit(r, 0, "", data)
	}
	return
}
  • 前台使用loginAfterFuncFrontend函数
// 复制代码
func loginAfterFuncFrontend(r *ghttp.Request, respData gtoken.Resp) {
	if !respData.Success() {
		respData.Code = 0
		r.Response.WriteJson(respData)
		return
	} else {
		respData.Code = 1
		//获得登录用户id
		userKey := respData.GetString("userKey")
		userId := gstr.StrEx(userKey, consts.GTokenFrontendPrefix)
		//根据id获得登录用户其他信息
		userInfo := entity.UserInfo{}
		err := dao.UserInfo.Ctx(context.TODO()).WherePri(userId).Scan(&userInfo)
		if err != nil {
			return
		}
		data := &frontend.LoginRes{
			Type:     consts.TokenType,
			Token:    respData.GetString("token"),
			ExpireIn: consts.GTokenExpireIn, //单位秒,
		}
		data.Name = userInfo.Name
		data.Avatar = userInfo.Avatar
		data.Sign = userInfo.Sign
		data.Status = uint8(userInfo.Status)
		response.JsonExit(r, 0, "", data)
	}
	return
}

这些函数在登录成功后生成token并返回给客户端,同时会查询用户的附加信息(如权限列表)

(3)鉴权后的处理:

  • 后台使用authAfterFunc函数
  • 前台使用authAfterFuncFrontend函数

这些函数负责在每次请求验证token后,将用户信息设置到请求上下文中

3. 路由保护

在cmd.go中,可以看到gtoken被用于保护需要登录才能访问的路由:

使用gtoken达到的作用:

1. 安全性保障

项目使用gtoken主要是为了保障用户信息安全,具体体现在:

  • 请求验证:确保只有登录用户才能访问敏感接口

  • 权限控制:管理员登录后,会查询其角色和对应的权限列表

  • 密码安全:登录时密码经过加密处理,不以明文形式出现

  • 过期机制:token有效期设置为10天,过期后需要重新登录

2. 提高用户体验

  • 保持登录状态:用户无需频繁登录

  • 多端登录支持:允许用户在多个设备上同时登录

  • 前后台分离:前台用户和管理员使用不同的认证系统,互不影响

3. 优化系统架构

  • 中间件方式:以中间件形式集成,代码侵入性小

  • 缓存使用:使用Redis缓存token信息,提高验证速度

  • 统一认证:所有需要认证的接口通过同一机制处理,代码更加统一和简洁

4. 身份信息传递

  • 登录后将用户ID、用户名等重要信息设置到请求上下文

  • 在后续处理中,控制器可以方便地获取当前登录用户的信息

  • 例如:r.SetCtxVar(consts.CtxUserId, userInfo.Id)使得用户ID可以在整个请求处理流程中被获取

引用:learnku.com/articles/17...

相关推荐
沸点小助手1 分钟前
🎆码力全开,万元现金大奖等你瓜分 | 4月金石计划
前端·人工智能·后端
东方窅瞳5 分钟前
SQL语言的物联网数据分析
开发语言·后端·golang
舒一笑7 分钟前
如何实现H5端对接钉钉登录并优雅扩展其他平台
java·后端·程序员
ker10 分钟前
Go语言底层(二) : GMP 模型
后端·面试
哈哈少儿86011 分钟前
手把手教你搭建轻量级电商风控平台-规则引擎篇
后端·架构
掘金酱11 分钟前
🎆码力全开,万元现金大奖等你瓜分 | 4月金石计划
前端·人工智能·后端
flzjkl12 分钟前
【源码】【Java并发】【ThreadLocal】适合中学者体质的ThreadLocal源码阅读
java·后端
用户849137175471615 分钟前
🔥Java校验注解终极PK:@Valid vs @Validated,你真的会用吗?
后端·spring
Home16 分钟前
二、Java性能优化--Nginx篇(二)
后端
fliter17 分钟前
性能比拼: MySQL vs PostgreSQL
后端