Browse Source

test: 国能单点登录

hsun 4 months ago
parent
commit
f9c76f386b
4 changed files with 536 additions and 194 deletions
  1. 431 193
      controllers/base_auth.go
  2. 1 0
      models/base.go
  3. 103 0
      services/user_login.go
  4. 1 1
      utils/constants.go

+ 431 - 193
controllers/base_auth.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"eta_gn/eta_api/cache"
 	"eta_gn/eta_api/models/system"
+	"eta_gn/eta_api/services"
 	"eta_gn/eta_api/services/alarm_msg"
 	"eta_gn/eta_api/services/data"
 	"fmt"
@@ -54,199 +55,199 @@ type BaseAuthController struct {
 	Lang    string `description:"当前语言类型,中文:zh;英文:en;默认:zh"`
 }
 
-func (c *BaseAuthController) Prepare() {
-	//fmt.Println("enter prepare")
-	method := c.Ctx.Input.Method()
-	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)
-				}
-			}
-			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
-			}
-
-			// 如果当前登录态是不可信设备的,那么需要做过期校验
-			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
-			}
-
-			fmt.Println("uri:", uri)
-
-			//fmt.Println(apiMap)
-			if !apiMap[uri] {
-				c.JSON(models.BaseResponse{Ret: 403, Msg: "无权访问!", ErrMsg: "无权访问!"}, false, false)
-				c.StopRun()
-				return
-			}
-		} else {
-			c.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)
-			c.StopRun()
-			return
-		}
-	}
-}
+//func (c *BaseAuthController) Prepare() {
+//	//fmt.Println("enter prepare")
+//	method := c.Ctx.Input.Method()
+//	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)
+//				}
+//			}
+//			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
+//			}
+//
+//			// 如果当前登录态是不可信设备的,那么需要做过期校验
+//			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
+//			}
+//
+//			fmt.Println("uri:", uri)
+//
+//			//fmt.Println(apiMap)
+//			if !apiMap[uri] {
+//				c.JSON(models.BaseResponse{Ret: 403, Msg: "无权访问!", ErrMsg: "无权访问!"}, false, false)
+//				c.StopRun()
+//				return
+//			}
+//		} else {
+//			c.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)
+//			c.StopRun()
+//			return
+//		}
+//	}
+//}
 
 func (c *BaseAuthController) ServeJSON(encoding ...bool) {
 	urlPath := c.Ctx.Request.URL.Path
@@ -467,3 +468,240 @@ func (c *BaseAuthController) logUri(respContent []byte, requestBody, ip string)
 	utils.ApiLog.Info("uri:%s, authorization:%s, requestBody:%s, responseBody:%s, ip:%s", c.Ctx.Input.URI(), authorization, requestBody, respContent, ip)
 	return
 }
+
+func (c *BaseAuthController) Prepare() {
+	//fmt.Println("enter prepare")
+	method := c.Ctx.Input.Method()
+	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)
+				}
+			}
+
+			// 单点登录逻辑
+			cookieVal := c.Ctx.Input.Header("CookieVal")
+			if cookieVal != "" {
+				// token不为空, 那么去校验一下token是否过期, 以及和cookieVal是否匹配
+				if authorization != "" {
+					tokenStr := authorization
+					tokenArr := strings.Split(tokenStr, "=")
+					token := tokenArr[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
+					}
+
+					// CookieVal不匹配、token验证失败、token过期,那么以cookieVal的用户去登录并返回4014
+					account := utils.MD5(session.UserName)
+					if session.UserName != cookieVal || !utils.CheckToken(account, token) || time.Now().After(session.ExpiredTime) {
+						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
+					}
+				}
+			}
+
+			// 正常逻辑
+			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
+			}
+
+			// 如果当前登录态是不可信设备的,那么需要做过期校验
+			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
+			}
+
+			fmt.Println("uri:", uri)
+
+			//fmt.Println(apiMap)
+			if !apiMap[uri] {
+				c.JSON(models.BaseResponse{Ret: 403, Msg: "无权访问!", ErrMsg: "无权访问!"}, false, false)
+				c.StopRun()
+				return
+			}
+		} else {
+			c.JSON(models.BaseResponse{Ret: 408, Msg: "请求异常,请联系客服!", ErrMsg: "POST之外的请求,暂不支持"}, false, false)
+			c.StopRun()
+			return
+		}
+	}
+}

+ 1 - 0
models/base.go

@@ -3,6 +3,7 @@ package models
 const (
 	BaseRespCodeAbnormalLogin = 4011 // 异常登录状态码
 	BaseRespCodeLoginErr      = 4012 // 账号或密码输入错误
+	BaseRespReLoginErr        = 4014 // 国能单点登录-用户账号切换/token失效的场景
 )
 
 type BaseResponse struct {

+ 103 - 0
services/user_login.go

@@ -419,3 +419,106 @@ func ThirdLogout(accessToken string) (err error) {
 
 	return
 }
+
+// UserLoginChange 切换用户
+func UserLoginChange(adminName string) (resp *system.LoginResp, err error) {
+	sysUser, e := system.GetSysUserByAdminName(adminName)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			err = fmt.Errorf("用户不存在: %s", adminName)
+			return
+		}
+		err = fmt.Errorf("获取用户失败, %v", e)
+		return
+	}
+
+	// 生成token
+	account := utils.MD5(sysUser.AdminName)
+	token := utils.GenToken(account)
+	sysSession := new(system.SysSession)
+	sysSession.UserName = sysUser.AdminName
+	sysSession.SysUserId = sysUser.AdminId
+	sysSession.ExpiredTime = time.Now().AddDate(0, 0, 90)
+	sysSession.IsRemember = 0 // 均需要做过期校验
+	sysSession.CreatedTime = time.Now()
+	sysSession.LastUpdatedTime = time.Now()
+	sysSession.AccessToken = token
+	if e := system.AddSysSession(sysSession); e != nil {
+		err = fmt.Errorf("新增session失败, %v", e)
+		return
+	}
+
+	// 修改最后登录时间
+	{
+		sysUser.LastLoginTime = time.Now().Format(utils.FormatDateTime)
+		sysUser.LastUpdatedTime = time.Now().Format(utils.FormatDateTime)
+		_ = sysUser.Update([]string{"LastLoginTime", "LastUpdatedTime"})
+	}
+
+	resp = new(system.LoginResp)
+	resp.Authorization = token
+	resp.Authorization = "authorization=" + token
+	resp.RealName = sysUser.RealName
+	resp.AdminName = sysUser.AdminName
+	resp.RoleName = sysUser.RoleName
+	resp.SysRoleTypeCode = sysUser.RoleTypeCode //系统角色编码
+	resp.RoleTypeCode = sysUser.RoleTypeCode
+	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_GROUP {
+		resp.RoleTypeCode = utils.ROLE_TYPE_CODE_FICC_SELLER
+	}
+	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_TEAM {
+		resp.RoleTypeCode = utils.ROLE_TYPE_CODE_FICC_SELLER
+	}
+	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT {
+		resp.RoleTypeCode = utils.ROLE_TYPE_CODE_FICC_SELLER
+	}
+	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP {
+		resp.RoleTypeCode = utils.ROLE_TYPE_CODE_RAI_SELLER
+	}
+	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_DEPARTMENT {
+		resp.RoleTypeCode = utils.ROLE_TYPE_CODE_RAI_SELLER
+	}
+	if sysUser.RoleName == utils.ROLE_NAME_FICC_DIRECTOR {
+		resp.RoleTypeCode = utils.ROLE_TYPE_CODE_FICC_SELLER
+	}
+	resp.AdminId = sysUser.AdminId
+	var productName string
+	productId := GetProductId(sysUser.RoleTypeCode)
+	if productId == 1 {
+		productName = utils.COMPANY_PRODUCT_FICC_NAME
+	} else if productId == 2 {
+		productName = utils.COMPANY_PRODUCT_RAI_NAME
+	} else {
+		productName = "admin"
+	}
+	resp.ProductName = productName
+	resp.Authority = sysUser.Authority
+
+	// 设置redis缓存
+	{
+		// 获取不可信的登录态,并将该登录态重置掉,不允许多次登录
+		noTrustLoginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN_NO_TRUST, sysUser.AdminId)
+		noTrustLoginId, _ := utils.Rc.RedisString(noTrustLoginKey)
+		if noTrustLoginId != `` { // 如果存在不可信设备,那么将其下架
+			oldNoTrustLoginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, noTrustLoginId)
+			_ = utils.Rc.Put(oldNoTrustLoginKey, "0", utils.LoginCacheTime*time.Minute)
+		}
+
+		// 如果当前是不可信设备,那么将其加入到不可信名单
+		loginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, sysSession.Id)
+		_ = utils.Rc.Put(loginKey, "1", utils.LoginCacheTime*time.Minute)
+		_ = utils.Rc.Put(noTrustLoginKey, sysSession.Id, utils.LoginCacheTime*time.Minute)
+	}
+
+	// 新增登录记录
+	go func() {
+		record := new(system.SysUserLoginRecord)
+		record.Uid = sysUser.AdminId
+		record.UserName = adminName
+		//record.Ip = this.Ctx.Input.IP()
+		record.Stage = "login"
+		record.CreateTime = time.Now()
+		_ = system.AddSysUserLoginRecord(record)
+	}()
+	return
+}

+ 1 - 1
utils/constants.go

@@ -365,7 +365,7 @@ const (
 
 const CrmEtaAuthorization = "NIi1RbEmH0C2rksXtPGDPBBgRgTZY87Q"
 
-const LoginCacheTime = 60 // 登录缓存时长, 分钟
+const LoginCacheTime = 8 * 60 // 登录缓存时长, 分钟
 
 // 对象存储客户端
 const (