Переглянути джерело

重构 Prepare函数中的 token 校验逻辑

- 提取 token校验逻辑到单独的 checkToken 函数中
- 优化了 token 解析和验证流程
- 移除了冗余的代码块,提高了代码可读性
- 现在支持 HEAD 请求方式
Roc 5 місяців тому
батько
коміт
e753354b1f
1 змінених файлів з 242 додано та 248 видалено
  1. 242 248
      controllers/base_auth.go

+ 242 - 248
controllers/base_auth.go

@@ -472,270 +472,264 @@ func (c *BaseAuthController) logUri(respContent []byte, requestBody, ip string)
 func (c *BaseAuthController) Prepare() {
 	//fmt.Println("enter prepare")
 	method := c.Ctx.Input.Method()
+	if method == `HEAD` {
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)
+		c.StopRun()
+		return
+	}
+	if method != "POST" && method != "GET" {
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)
+		c.StopRun()
+		return
+	}
 	uri := c.Ctx.Input.URI()
 	//fmt.Println("Url:", uri)
-	if method != "HEAD" {
-		if method == "POST" || method == "GET" {
-			// 当前语言
-			{
-				lang := c.Ctx.Input.Header("Lang")
-				if lang == "" {
-					lang = utils.ZhLangVersion
-				}
-				c.Lang = lang
-			}
 
-			authorization := c.Ctx.Input.Header("authorization")
-			if authorization == "" {
-				authorization = c.Ctx.Input.Header("Authorization")
-			}
-			if authorization == "" {
-				newAuthorization := c.GetString("authorization")
-				if newAuthorization != `` {
-					authorization = "authorization=" + newAuthorization
-				} else {
-					newAuthorization = c.GetString("Authorization")
-					authorization = "authorization=" + newAuthorization
-				}
-			} else {
-				if strings.Contains(authorization, ";") {
-					authorization = strings.Replace(authorization, ";", "$", 1)
-				}
-			}
-			if authorization == "" {
-				strArr := strings.Split(uri, "?")
-				for k, v := range strArr {
-					fmt.Println(k, v)
-				}
-				if len(strArr) > 1 {
-					authorization := strArr[1]
-					authorization = strings.Replace(authorization, "Authorization", "authorization", -1)
-					fmt.Println(authorization)
-				}
-			}
+	// 当前语言
+	{
+		lang := c.Ctx.Input.Header("Lang")
+		if lang == "" {
+			lang = utils.ZhLangVersion
+		}
+		c.Lang = lang
+	}
 
-			// 单点登录逻辑
-			var cookieVal string
-			cookieVal = c.Ctx.Input.Header("CookieVal")
-			if cookieVal == "" {
-				cookieVal = c.Ctx.Input.Header("cookieval")
-			}
-			if cookieVal == "" {
-				cookieVal = c.Ctx.Input.Header("Cookieval")
-			}
-			fmt.Println("cookieVal:", cookieVal)
-			if cookieVal != "" {
-				// token不为空, 那么去校验一下token是否过期, 以及和cookieVal是否匹配
-				if authorization != "" {
-					tokenStr := authorization
-					tokenArr := strings.Split(tokenStr, "=")
-					token := tokenArr[1]
-
-					// 找不到session, 也直接切CookieValue中的用户登录
-					session, err := system.GetSysSessionByToken(token)
-					//if err != nil {
-					//	if utils.IsErrNoRow(err) {
-					//		c.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "Token 信息已变更:Token: " + token}, false, false)
-					//		c.StopRun()
-					//		return
-					//	}
-					//	c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取用户信息异常,Eerr:" + err.Error()}, false, false)
-					//	c.StopRun()
-					//	return
-					//}
-					//if session == nil {
-					//	c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "sesson is empty "}, false, false)
-					//	c.StopRun()
-					//	return
-					//}
-					if err != nil || session == nil {
-						newLogin, e := services.UserLoginChange(cookieVal)
-						if e != nil {
-							c.JSON(models.BaseResponse{Ret: 408, Msg: "重登录失败,请稍后重试!", ErrMsg: fmt.Sprint(e)}, false, false)
-							c.StopRun()
-							return
-						}
-						c.JSON(models.BaseResponse{Ret: models.BaseRespReLoginErr, Msg: "用户切换,请刷新页面", ErrMsg: "user exchanged", Data: newLogin}, false, false)
-						c.StopRun()
-						return
-					}
-
-					// CookieVal不匹配、token验证失败、session以及redis中的token过期,那么以cookieVal的用户去登录并返回4014
-					account := utils.MD5(session.UserName)
-					loginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, session.Id)
-					loginCache, _ := utils.Rc.RedisString(loginKey)
-					if session.UserName != cookieVal || !utils.CheckToken(account, token) || time.Now().After(session.ExpiredTime) || (session.IsRemember != 1 && loginCache == ``) {
-						newLogin, e := services.UserLoginChange(cookieVal)
-						if e != nil {
-							c.JSON(models.BaseResponse{Ret: 408, Msg: "重登录失败,请稍后重试!", ErrMsg: fmt.Sprint(e)}, false, false)
-							c.StopRun()
-							return
-						}
-						c.JSON(models.BaseResponse{Ret: models.BaseRespReLoginErr, Msg: "用户切换,请刷新页面", ErrMsg: "user exchanged", Data: newLogin}, false, false)
-						c.StopRun()
-						return
-					}
-				} else {
-					// Token空了, 以Cookie为准重新登录
-					newLogin, e := services.UserLoginChange(cookieVal)
-					if e != nil {
-						c.JSON(models.BaseResponse{Ret: 408, Msg: "重登录失败,请稍后重试!", ErrMsg: fmt.Sprint(e)}, false, false)
-						c.StopRun()
-						return
-					}
-					c.JSON(models.BaseResponse{Ret: models.BaseRespReLoginErr, Msg: "用户切换,请刷新页面", ErrMsg: "user exchanged", Data: newLogin}, false, false)
-					c.StopRun()
-					return
-				}
-			}
+	isOk, token, resp := checkToken(c)
+	if !isOk {
+		_ = c.JSON(resp, false, false)
+		c.StopRun()
+		return
+	}
 
-			// 正常逻辑
-			if authorization == "" {
-				c.JSON(models.BaseResponse{Ret: 408, Msg: "请重新授权!", ErrMsg: "请重新授权:Token is empty or account is empty"}, false, false)
-				c.StopRun()
-				return
-			}
-			//authorizationArr := strings.Split(authorization, "$")
-			//if len(authorizationArr) <= 1 {
-			//	c.JSON(models.BaseResponse{Ret: 408, Msg: "请重新授权!", ErrMsg: "请重新授权:Token is empty or account is empty"}, false, false)
-			//	c.StopRun()
-			//	return
-			//}
-			tokenStr := authorization
-			tokenArr := strings.Split(tokenStr, "=")
-			token := tokenArr[1]
-
-			//accountStr := authorizationArr[1]
-			//accountArr := strings.Split(accountStr, "=")
-			//account := accountArr[1]
-
-			session, err := system.GetSysSessionByToken(token)
-			if err != nil {
-				if utils.IsErrNoRow(err) {
-					c.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "Token 信息已变更:Token: " + token}, false, false)
-					c.StopRun()
-					return
-				}
-				c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取用户信息异常,Eerr:" + err.Error()}, false, false)
-				c.StopRun()
-				return
-			}
-			if session == nil {
-				c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "sesson is empty "}, false, false)
-				c.StopRun()
-				return
-			}
-			//校验token是否合法
-			// JWT校验Token和Account
-			account := utils.MD5(session.UserName)
-			if !utils.CheckToken(account, token) {
-				c.JSON(models.BaseResponse{Ret: 408, Msg: "鉴权失败,请重新登录!", ErrMsg: "登录失效,请重新登陆!,CheckToken Fail"}, false, false)
-				c.StopRun()
-				return
-			}
-			if time.Now().After(session.ExpiredTime) {
-				c.JSON(models.BaseResponse{Ret: 408, Msg: "请重新登录!", ErrMsg: "获取用户信息异常,Eerr:" + err.Error()}, false, false)
-				c.StopRun()
-				return
-			}
-			admin, err := system.GetSysUserById(session.SysUserId)
-			if err != nil {
-				if utils.IsErrNoRow(err) {
-					c.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "获取admin 信息失败 " + strconv.Itoa(session.SysUserId)}, false, false)
-					c.StopRun()
-					return
-				}
-				c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取admin信息异常,Eerr:" + err.Error()}, false, false)
-				c.StopRun()
-				return
-			}
-			if admin == nil {
-				c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "admin is empty "}, false, false)
-				c.StopRun()
-				return
-			}
-			//如果不是启用状态
-			if admin.Enabled != 1 {
-				c.JSON(models.BaseResponse{Ret: 408, Msg: "账户信息异常!", ErrMsg: "账户被禁用,不允许登陆!,CheckToken Fail"}, false, false)
-				c.StopRun()
-				return
-			}
+	//accountStr := authorizationArr[1]
+	//accountArr := strings.Split(accountStr, "=")
+	//account := accountArr[1]
 
-			// 如果当前登录态是不可信设备的,那么需要做过期校验
-			if session.IsRemember != 1 {
-				loginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, session.Id)
-				loginInfo, _ := utils.Rc.RedisString(loginKey)
-				if loginInfo == `` {
-					c.JSON(models.BaseResponse{Ret: 408, Msg: "超时未操作,系统自动退出!", ErrMsg: "超时未操作,系统自动退出!"}, false, false)
-					c.StopRun()
-					return
-				}
+	session, err := system.GetSysSessionByToken(token)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			c.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "Token 信息已变更:Token: " + token}, false, false)
+			c.StopRun()
+			return
+		}
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取用户信息异常,Eerr:" + err.Error()}, false, false)
+		c.StopRun()
+		return
+	}
+	if session == nil {
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "sesson is empty "}, false, false)
+		c.StopRun()
+		return
+	}
+	//校验token是否合法
+	// JWT校验Token和Account
+	account := utils.MD5(session.UserName)
+	if !utils.CheckToken(account, token) {
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "鉴权失败,请重新登录!", ErrMsg: "登录失效,请重新登陆!,CheckToken Fail"}, false, false)
+		c.StopRun()
+		return
+	}
+	if time.Now().After(session.ExpiredTime) {
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "请重新登录!", ErrMsg: "获取用户信息异常,Eerr:" + err.Error()}, false, false)
+		c.StopRun()
+		return
+	}
+	admin, err := system.GetSysUserById(session.SysUserId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			c.JSON(models.BaseResponse{Ret: 408, Msg: "信息已变更,请重新登陆!", ErrMsg: "获取admin 信息失败 " + strconv.Itoa(session.SysUserId)}, false, false)
+			c.StopRun()
+			return
+		}
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "获取admin信息异常,Eerr:" + err.Error()}, false, false)
+		c.StopRun()
+		return
+	}
+	if admin == nil {
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "网络异常,请稍后重试!", ErrMsg: "admin is empty "}, false, false)
+		c.StopRun()
+		return
+	}
+	//如果不是启用状态
+	if admin.Enabled != 1 {
+		c.JSON(models.BaseResponse{Ret: 408, Msg: "账户信息异常!", ErrMsg: "账户被禁用,不允许登陆!,CheckToken Fail"}, false, false)
+		c.StopRun()
+		return
+	}
 
-				//if loginInfo != "1" {
-				//	lastLoginTime := admin.LastLoginTime
-				//
-				//	lastLoginTimeObj, err := time.Parse(utils.FormatDateWallWithLoc, lastLoginTime)
-				//	fmt.Println(lastLoginTimeObj, err)
-				//
-				//	msg := `该账号于` + lastLoginTimeObj.Format(utils.FormatDateTime) + "在其他网络登录。此客户端已退出登录。"
-				//	c.JSON(models.BaseResponse{Ret: 408, Msg: msg, ErrMsg: msg}, false, false)
-				//	c.StopRun()
-				//	return
-				//}
-
-				// 如果是ETA体验版-更新活跃时长/更新登录时长的接口请求, 则不更新Token时长
-				if uri != `/adminapi/eta_trial/user/login_duration` && uri != `/adminapi/eta_trial/user/active` {
-					utils.Rc.Put(loginKey, "1", utils.LoginCacheTime*time.Minute)
-					// 不信任名单也同步更新
-					noTrustLoginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN_NO_TRUST, admin.AdminId)
-					utils.Rc.Put(noTrustLoginKey, session.Id, utils.LoginCacheTime*time.Minute)
-				}
-			}
+	// 如果当前登录态是不可信设备的,那么需要做过期校验
+	if session.IsRemember != 1 {
+		loginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, session.Id)
+		loginInfo, _ := utils.Rc.RedisString(loginKey)
+		if loginInfo == `` {
+			c.JSON(models.BaseResponse{Ret: 408, Msg: "超时未操作,系统自动退出!", ErrMsg: "超时未操作,系统自动退出!"}, false, false)
+			c.StopRun()
+			return
+		}
+
+		//if loginInfo != "1" {
+		//	lastLoginTime := admin.LastLoginTime
+		//
+		//	lastLoginTimeObj, err := time.Parse(utils.FormatDateWallWithLoc, lastLoginTime)
+		//	fmt.Println(lastLoginTimeObj, err)
+		//
+		//	msg := `该账号于` + lastLoginTimeObj.Format(utils.FormatDateTime) + "在其他网络登录。此客户端已退出登录。"
+		//	c.JSON(models.BaseResponse{Ret: 408, Msg: msg, ErrMsg: msg}, false, false)
+		//	c.StopRun()
+		//	return
+		//}
+
+		// 如果是ETA体验版-更新活跃时长/更新登录时长的接口请求, 则不更新Token时长
+		if uri != `/adminapi/eta_trial/user/login_duration` && uri != `/adminapi/eta_trial/user/active` {
+			utils.Rc.Put(loginKey, "1", utils.LoginCacheTime*time.Minute)
+			// 不信任名单也同步更新
+			noTrustLoginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN_NO_TRUST, admin.AdminId)
+			utils.Rc.Put(noTrustLoginKey, session.Id, utils.LoginCacheTime*time.Minute)
+		}
+	}
+
+	admin.RoleTypeCode = GetSysUserRoleTypeCode(admin.RoleTypeCode)
+	c.SysUser = admin
+	c.Session = session
+
+	//接口权限校验
+	roleId := admin.RoleId
+	list, e := system.GetMenuButtonApisByRoleId(roleId)
+	if e != nil {
+		c.JSON(models.BaseResponse{Ret: 403, Msg: "获取接口权限出错!", ErrMsg: "获取接口权限出错!"}, false, false)
+		c.StopRun()
+		return
+	}
+	var api string
+	for _, v := range list {
+		if v.Api != "" {
+			api += v.Api + "&"
+		}
+	}
+
+	//fmt.Println(api)
+	//处理uri请求,去除前缀和参数
+	api = strings.TrimRight(api, "&")
+	uri = strings.Replace(uri, "/adminapi", "", 1)
+	uris := strings.Split(uri, "?")
+	uri = uris[0]
+	//fmt.Println("uri:", uri)
+	apis := strings.Split(api, "&")
+	apiMap := make(map[string]bool, 0)
+	for _, s := range apis {
+		apiMap[s] = true
+	}
 
-			admin.RoleTypeCode = GetSysUserRoleTypeCode(admin.RoleTypeCode)
-			c.SysUser = admin
-			c.Session = session
+	fmt.Println("uri:", uri)
 
-			//接口权限校验
-			roleId := admin.RoleId
-			list, e := system.GetMenuButtonApisByRoleId(roleId)
+	//fmt.Println(apiMap)
+	if !apiMap[uri] {
+		c.JSON(models.BaseResponse{Ret: 403, Msg: "无权访问!", ErrMsg: "无权访问!"}, false, false)
+		c.StopRun()
+		return
+	}
+
+}
+
+// checkToken
+// @Description: 校验token
+// @author: Roc
+// @datetime 2024-10-30 11:29:37
+// @param c *BaseAuthController
+// @return isOk bool
+// @return token string
+// @return resp models.BaseResponse
+func checkToken(c *BaseAuthController) (isOk bool, token string, resp models.BaseResponse) {
+	// 是否校验成功
+	isOk = true
+	uri := c.Ctx.Input.URI()
+	authorization := c.Ctx.Input.Header("authorization")
+	if authorization == "" {
+		authorization = c.Ctx.Input.Header("Authorization")
+	}
+	if authorization == "" {
+		newAuthorization := c.GetString("authorization")
+		if newAuthorization != `` {
+			authorization = "authorization=" + newAuthorization
+		} else {
+			newAuthorization = c.GetString("Authorization")
+			authorization = "authorization=" + newAuthorization
+		}
+	} else {
+		if strings.Contains(authorization, ";") {
+			authorization = strings.Replace(authorization, ";", "$", 1)
+		}
+	}
+	if authorization == "" {
+		strArr := strings.Split(uri, "?")
+		for k, v := range strArr {
+			fmt.Println(k, v)
+		}
+		if len(strArr) > 1 {
+			authorization = strArr[1]
+			authorization = strings.Replace(authorization, "Authorization", "authorization", -1)
+			fmt.Println(authorization)
+		}
+	}
+	if authorization != "" {
+		tokenStr := authorization
+		tokenArr := strings.Split(tokenStr, "=")
+		token = tokenArr[1]
+	}
+
+	// 单点登录逻辑
+	aiUser := c.Ctx.GetCookie("ai_user")
+	fmt.Println("ai_user:", aiUser)
+	if aiUser != "" {
+		// Token空了, 以Cookie为准重新登录
+		if token == `` {
+			newLogin, e := services.UserLoginChange(aiUser)
 			if e != nil {
-				c.JSON(models.BaseResponse{Ret: 403, Msg: "获取接口权限出错!", ErrMsg: "获取接口权限出错!"}, false, false)
-				c.StopRun()
-				return
-			}
-			var api string
-			for _, v := range list {
-				if v.Api != "" {
-					api += v.Api + "&"
-				}
+				resp = models.BaseResponse{Ret: 408, Msg: "重登录失败,请稍后重试!", ErrMsg: fmt.Sprint(e)}
+			} else {
+				resp = models.BaseResponse{Ret: models.BaseRespReLoginErr, Msg: "用户切换,请刷新页面", ErrMsg: "user exchanged", Data: newLogin}
 			}
+			isOk = false
+			return
+		}
 
-			//fmt.Println(api)
-			//处理uri请求,去除前缀和参数
-			api = strings.TrimRight(api, "&")
-			uri = strings.Replace(uri, "/adminapi", "", 1)
-			uris := strings.Split(uri, "?")
-			uri = uris[0]
-			//fmt.Println("uri:", uri)
-			apis := strings.Split(api, "&")
-			apiMap := make(map[string]bool, 0)
-			for _, s := range apis {
-				apiMap[s] = true
+		// todo 将aiUser与session进行关联
+		// token不为空, 那么去校验一下token是否过期, 以及和cookieVal是否匹配
+		// 找不到session, 也直接切CookieValue中的用户登录
+		session, err := system.GetSysSessionByToken(token)
+		if err != nil {
+			newLogin, e := services.UserLoginChange(aiUser)
+			if e != nil {
+				resp = models.BaseResponse{Ret: 408, Msg: "重登录失败,请稍后重试!", ErrMsg: fmt.Sprint(e)}
+			} else {
+				resp = models.BaseResponse{Ret: models.BaseRespReLoginErr, Msg: "用户切换,请刷新页面", ErrMsg: "user exchanged", Data: newLogin}
 			}
+			isOk = false
+			return
+		}
 
-			fmt.Println("uri:", uri)
-
-			//fmt.Println(apiMap)
-			if !apiMap[uri] {
-				c.JSON(models.BaseResponse{Ret: 403, Msg: "无权访问!", ErrMsg: "无权访问!"}, false, false)
-				c.StopRun()
-				return
+		// CookieVal不匹配、token验证失败、session以及redis中的token过期,那么以cookieVal的用户去登录并返回4014
+		account := utils.MD5(session.UserName)
+		loginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, session.Id)
+		loginCache, _ := utils.Rc.RedisString(loginKey)
+		if session.UserName != aiUser || !utils.CheckToken(account, token) || time.Now().After(session.ExpiredTime) || (session.IsRemember != 1 && loginCache == ``) {
+			newLogin, e := services.UserLoginChange(aiUser)
+			if e != nil {
+				resp = models.BaseResponse{Ret: 408, Msg: "重登录失败,请稍后重试!", ErrMsg: fmt.Sprint(e)}
+			} else {
+				resp = models.BaseResponse{Ret: models.BaseRespReLoginErr, Msg: "用户切换,请刷新页面", ErrMsg: "user exchanged", Data: newLogin}
 			}
-		} else {
-			c.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)
-			c.StopRun()
+			isOk = false
 			return
 		}
 	}
+
+	// 正常逻辑
+	if token == "" {
+		resp = models.BaseResponse{Ret: 408, Msg: "请重新授权!", ErrMsg: "请重新授权:Token is empty or account is empty"}
+		isOk = false
+		return
+	}
+
+	return
 }