生产环境用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了。

相关推荐
斯普信专业组3 小时前
rabbitmq-k8s下双架构镜像+手动sts部署完全文档(下)
架构·kubernetes·rabbitmq
美狐美颜SDK开放平台4 小时前
直播美颜sdk特效功能架构全解析:从图像处理到AI渲染的技术演进
图像处理·人工智能·算法·架构·1024程序员节·美颜sdk·直播美颜sdk
小王不爱笑1324 小时前
Maven 进阶与私服架构
java·架构·maven
青鱼入云4 小时前
Sentinel介绍
微服务·sentinel
青鱼入云4 小时前
Feign如何集成Sentinel
spring cloud·微服务·sentinel
Moniane11 小时前
A2A+MCP构建智能体协作生态:下一代分布式人工智能架构解析
人工智能·分布式·架构
码界奇点12 小时前
Apache IoTDB 架构特性与 PrometheusGrafana 监控体系部署实践
架构·apache·grafana·prometheus·iotdb
꒰ঌ 安卓开发໒꒱12 小时前
RabbitMQ面试全解析:从核心概念到高可用架构
面试·架构·rabbitmq
JZC_xiaozhong13 小时前
异构系统集成提速:重构企业数据流转架构
大数据·重构·架构·数据分析·etl工程师·数据集成与应用集成·异构数据整合