package SsoUtil import ( "dsBigData/Utils/ConfigUtil" "dsBigData/Utils/RedisUtil" "encoding/base64" "github.com/gin-gonic/gin" "github.com/gomodule/redigo/redis" "github.com/sirupsen/logrus" "strconv" "strings" ) /** 功能:检查是不是合法用户 作者:黄海 时间:2020-02-22 */ func IsAuthority(c *gin.Context) (bool, string) { //检查Header头中是不是存在ds_sso_sessionid,就是说,如果客户端不支持Cookie(比如手机),可以在Header中构建ds_sso_sessionid sessionId := "" //从 Header中获取会话ID sessionId = c.Request.Header.Get(ConfigUtil.SessionId) //如果没有找到,就到 cookie里继续寻找 if len(sessionId) == 0 { cookie, e := c.Request.Cookie(ConfigUtil.SessionId) if e == nil { //如果成功获取到的话 sessionId = cookie.Value } } //如果两个位置都没有找到 if len(sessionId) == 0 { return false, "" } else { //有这个值,判断一下是不是正确 _map := RedisUtil.HGETALL(ConfigUtil.SessionId + "_" + sessionId) if len(_map) == 0 { //清除非法cookie,资料参考:https://www.tizi365.com/archives/273.html c.SetCookie(ConfigUtil.SessionId, "", -1, "/", "", false, true) return false, sessionId } else { return true, sessionId } } } /** 功能:判断当前登录人员是不是处于登录状态 作者:黄海 时间:2020-02-25 */ func IsLoginStatus(username string) (bool, string) { var value = "" var r = true value, err := redis.String(RedisUtil.GET(ConfigUtil.SearchSessionIdPrefix + username)) if err != nil { r = false } return r, value } /** 功能:写入统一认证的信息 作者:黄海 时间:2020-02-22 */ func WriteSsoInfo(c *gin.Context, device string, identityId int64, personId int64, username string, personName string, dsSsoSessionid string) { //下面应该是双向的redis存储,即:(1)通过登录名能找到对应的会话ID,(2)通过会话ID,可以解析出是哪种设备,哪个身份,哪个人员ID //一、写入登录名与会话的对应关系,由四部分组成,前缀+设备类型+身份+人员编号,通过这个键值可以查找到对应的会话 SearchSsoKey := ConfigUtil.SearchSessionIdPrefix + "_" + device + "_" + strconv.FormatInt(identityId, 10) + "_" + strconv.FormatInt(personId, 10) //写入redis RedisUtil.SET(SearchSsoKey, ConfigUtil.SessionId+"_"+dsSsoSessionid) //加上过期时间 RedisUtil.EXPIRE(SearchSsoKey) //二、写入SESSION_ID _map := make(map[string]interface{}) _map["device"] = device _map["identity_id"] = identityId _map["person_id"] = personId _map["username"] = username _map["person_name"] = personName RedisUtil.HMSET(ConfigUtil.SessionId+"_"+dsSsoSessionid, _map) //加上过期时间 RedisUtil.EXPIRE(ConfigUtil.SessionId + "_" + dsSsoSessionid) //三、写入主域的COOKIE值 c.SetCookie(ConfigUtil.SessionId, dsSsoSessionid, 0, "/", "", false, true) } /** 功能: 清理统一认证的登录信息,包括清理cookie+redis缓存 作者:黄海 时间:2020-02-22 */ func ClearSsoInfo(sessionId string, c *gin.Context) string { //一、删除人员与 sessionId的映射关系 DeletePersonSessionReleation(sessionId) //二、删除redis中的会话id DeleteSessionId(sessionId) //三、清除cookie deleteSsoCookie(c) return sessionId } /** 功能:删除人员与会话的映射关系 作者:黄海 时间:2020-02-25 */ func DeletePersonSessionReleation(sessionId string) { //一、删除人员与 sessionId的映射关系 var identityId = -1 var personId = -1 var deviceId = -1 deviceId, identityId, personId = AnalyzeSessionId(sessionId) //通过会话ID获取到人员的信息 //删除人员与会话的对应关系 SearchSsoKey := ConfigUtil.SearchSessionIdPrefix + "_" + strconv.Itoa(deviceId) + "_" + strconv.Itoa(identityId) + "_" + strconv.Itoa(personId) RedisUtil.DEL(SearchSsoKey) } /** 功能:解析SessionId的内容,换算出设备,身份和人员ID 作者:黄海 时间:2020-02-25 */ func AnalyzeSessionId(sessionId string) (int, int, int) { var identityId = -1 var personId = -1 var deviceId = -1 r, err := base64.RawURLEncoding.DecodeString(sessionId) if err != nil { logrus.Errorln(err) } else { s := string(r) array := strings.Split(s, "_") if len(array) > 1 { deviceId, _ = strconv.Atoi(array[0]) identityId, _ = strconv.Atoi(array[1]) personId, _ = strconv.Atoi(array[2]) } } return deviceId, identityId, personId } /** 功能:删除redis中的会话id 作者:黄海 时间:2020-02-25 */ func DeleteSessionId(sessionId string) { //删除redis中的记录 RedisUtil.DEL(ConfigUtil.SessionId + "_" + sessionId) } /** 功能:读取统一认证的cookie值 作者:黄海 时间:2020-02-22 */ func ReadSsoCookie(c *gin.Context) string { cookie, e := c.Request.Cookie(ConfigUtil.SessionId) if e == nil { return cookie.Value } else { return "" } } /** 功能:删除统一认证的cookie信息 作者:黄海 时间:2020-02-22 */ func deleteSsoCookie(c *gin.Context) { c.SetCookie(ConfigUtil.SessionId, "", -1, "/", "", false, true) }