生产环境用Go语言完成微服务搭建和业务融入

业务场景:已经有一套在运行的php项目,但是性能和灵活性不足。需要开发部署一套go语言服务,但是要能兼容前项目的鉴权规则。那么我们除了将php的鉴权模块独立出来,放到网关,再就是在go服务里写一个同逻辑的中间件。

我发现了项目中这张表里存了用户的token和创建销毁时间,也就不难猜出,原来的后端是通过这里判断token有效和时间的。

那么作为后来者,我也可以通过这张表去对比前端携带的token是否合法,就有了以下的代码。

Go 复制代码
// Token验证中间件(仅通过token验证)
func TokenAuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从请求头获取token
		token := c.GetHeader("Authorization")
		if token == "" {
			c.JSON(http.StatusUnauthorized, gin.H{
				"success": false,
				"error":   "未授权",
			})
			c.Abort()
			return
		}

		// 去除可能的"Bearer "前缀
		if strings.HasPrefix(token, "Bearer ") {
			token = strings.TrimPrefix(token, "Bearer ")
		}
		log.Printf("前端token%s:", token)
		// 验证token有效性
		isValid := verifyToken(token)
		if !isValid {
			c.JSON(http.StatusUnauthorized, gin.H{
				"success": false,
				"error":   "未授权",
			})
			c.Abort()
			return
		}

		// token验证通过,继续执行后续逻辑
		c.Next()
	}
}

// 通过token验证有效性
func verifyToken(token string) bool {
	// 查询token对应的记录
	type UserToken struct {
		Createtime int64 `json:"createtime"`
		Expiretime int64 `json:"expiretime"`
	}

	var userToken UserToken

	// 查询该token对应的记录
	query := `
        SELECT createtime, expiretime 
        FROM fa_user_token 
        WHERE token = ? 
        LIMIT 1
    `

	err := dbManager.GetDB().QueryRow(query, token).Scan(
		&userToken.Createtime,
		&userToken.Expiretime,
	)

	if err != nil {
		if err == sql.ErrNoRows {
			log.Printf("token不存在: %s", token)
		} else {
			log.Printf("查询token失败: %s, 错误: %v", token, err)
		}
		return false
	}

	// 获取当前时间戳(秒级)
	currentTime := time.Now().Unix()

	// 验证是否过期
	isExpired := false

	// 1. 验证是否超过两个月(5184000秒 = 60天)
	twoMonthsAgo := currentTime - 5184000
	//2592000 一个月
	//1296000 半个月
	if userToken.Createtime < twoMonthsAgo {
		isExpired = true
		log.Printf("token已超过两个月: %s", token)
	}

	// 2. 检查是否已主动退出/销毁(expiretime字段有值且小于当前时间)
	if userToken.Expiretime > 0 {
		if currentTime > userToken.Expiretime {
			isExpired = true
			log.Printf("token已主动退出/销毁: %s, 销毁时间: %d", token, userToken.Expiretime)
		} else {
			log.Printf("token有效期内: %s, 过期时间: %d", token, userToken.Expiretime)
		}
	} else {
		log.Printf("token无过期时间设置: %s", token)
	}

	if isExpired {
		return false
	}

	log.Printf("token验证成功: %s", token)
	return true
}

使用时作为中间件放入到函数中当做参数传入就ok了。

相关推荐
GreenTea2 小时前
我把 Agent 的 while 循环拆掉了:一种你可能没想到的 Agent 架构
前端·后端·架构
m0_587383002 小时前
广州24小时自助健身房解决方案实战指南与系统部署要点
java·spring·小程序·架构·需求分析
分布式存储与RustFS4 小时前
纠删码到底吃掉了多少容量:EC:4、EC:8 的利用率与容错怎么算
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
狂奔蜗牛(bradley)4 小时前
拒绝SOEM黑盒!死磕EtherCAT主站:ARM+FPGA架构、DC同步与状态机修复等,50+篇实战开发文档全公开
arm开发·fpga开发·架构
辛迪聊物业数字化5 小时前
智慧社区SaaS平台架构拆解:从物业收费到IoT联动的落地实现
物联网·架构
无序的浪5 小时前
测试博客-基于微服务的在线判题系统
java·spring cloud·docker·微服务·测试·在线判题
念何架构之路6 小时前
zap日志SugaredLogger 剖析
云原生·golang
天远Date Lab6 小时前
微服务架构实战:基于天远学历信息高级版构建自动化人才准入网关
人工智能·微服务·架构·自动化
头茬韭菜7 小时前
DataFlow 深度分析与技术文档系列计划
架构·dataflow
Thneonl7 小时前
消息队列选型决策树:RabbitMQ vs Kafka vs Redis Streams
后端·架构