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

相关推荐
鹏北海-RemHusband3 分钟前
从零到一:基于 micro-app 的企业级微前端模板完整实现指南
前端·微服务·架构
7哥♡ۣۖᝰꫛꫀꪝۣℋ8 分钟前
Spring-cloud\Eureka
java·spring·微服务·eureka
2的n次方_2 小时前
Runtime 内存管理深化:推理批处理下的内存复用与生命周期精细控制
c语言·网络·架构
前端市界3 小时前
用 React 手搓一个 3D 翻页书籍组件,呼吸海浪式翻页,交互体验带感!
前端·架构·github
文艺理科生3 小时前
Nginx 路径映射深度解析:从本地开发到生产交付的底层哲学
前端·后端·架构
C澒3 小时前
Vue 项目渐进式迁移 React:组件库接入与跨框架协同技术方案
前端·vue.js·react.js·架构·系统架构
消失的旧时光-19434 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
惊讶的猫4 小时前
OpenFeign(声明式HTTP客户端)
网络·网络协议·http·微服务·openfeign
鹏北海5 小时前
micro-app 微前端项目部署指南
前端·nginx·微服务
L543414465 小时前
告别代码堆砌匠厂架构让你的系统吞吐量翻倍提升
大数据·人工智能·架构·自动化·rpa