parent
912ec51315
commit
e7e3b6dd15
@ -1,46 +1,46 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Open_IM/pkg/utils"
|
"Open_IM/pkg/common/constant"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_PlatformIDToName(t *testing.T) {
|
func Test_PlatformIDToName(t *testing.T) {
|
||||||
assert.Equal(t, utils.PlatformIDToName(1), "IOS")
|
assert.Equal(t, constant.PlatformIDToName(1), "IOS")
|
||||||
assert.Equal(t, utils.PlatformIDToName(2), "Android")
|
assert.Equal(t, constant.PlatformIDToName(2), "Android")
|
||||||
assert.Equal(t, utils.PlatformIDToName(3), "Windows")
|
assert.Equal(t, constant.PlatformIDToName(3), "Windows")
|
||||||
assert.Equal(t, utils.PlatformIDToName(4), "OSX")
|
assert.Equal(t, constant.PlatformIDToName(4), "OSX")
|
||||||
assert.Equal(t, utils.PlatformIDToName(5), "Web")
|
assert.Equal(t, constant.PlatformIDToName(5), "Web")
|
||||||
assert.Equal(t, utils.PlatformIDToName(6), "MiniWeb")
|
assert.Equal(t, constant.PlatformIDToName(6), "MiniWeb")
|
||||||
assert.Equal(t, utils.PlatformIDToName(7), "Linux")
|
assert.Equal(t, constant.PlatformIDToName(7), "Linux")
|
||||||
|
|
||||||
assert.Equal(t, utils.PlatformIDToName(0), "")
|
assert.Equal(t, constant.PlatformIDToName(0), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_PlatformNameToID(t *testing.T) {
|
func Test_PlatformNameToID(t *testing.T) {
|
||||||
assert.Equal(t, utils.PlatformNameToID("IOS"), int32(1))
|
assert.Equal(t, constant.PlatformNameToID("IOS"), int32(1))
|
||||||
assert.Equal(t, utils.PlatformNameToID("Android"), int32(2))
|
assert.Equal(t, constant.PlatformNameToID("Android"), int32(2))
|
||||||
assert.Equal(t, utils.PlatformNameToID("Windows"), int32(3))
|
assert.Equal(t, constant.PlatformNameToID("Windows"), int32(3))
|
||||||
assert.Equal(t, utils.PlatformNameToID("OSX"), int32(4))
|
assert.Equal(t, constant.PlatformNameToID("OSX"), int32(4))
|
||||||
assert.Equal(t, utils.PlatformNameToID("Web"), int32(5))
|
assert.Equal(t, constant.PlatformNameToID("Web"), int32(5))
|
||||||
assert.Equal(t, utils.PlatformNameToID("MiniWeb"), int32(6))
|
assert.Equal(t, constant.PlatformNameToID("MiniWeb"), int32(6))
|
||||||
assert.Equal(t, utils.PlatformNameToID("Linux"), int32(7))
|
assert.Equal(t, constant.PlatformNameToID("Linux"), int32(7))
|
||||||
|
|
||||||
assert.Equal(t, utils.PlatformNameToID("UnknownDevice"), int32(0))
|
assert.Equal(t, constant.PlatformNameToID("UnknownDevice"), int32(0))
|
||||||
assert.Equal(t, utils.PlatformNameToID(""), int32(0))
|
assert.Equal(t, constant.PlatformNameToID(""), int32(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_PlatformNameToClass(t *testing.T) {
|
func Test_PlatformNameToClass(t *testing.T) {
|
||||||
assert.Equal(t, utils.PlatformNameToClass("IOS"), "Mobile")
|
assert.Equal(t, constant.PlatformNameToClass("IOS"), "Mobile")
|
||||||
assert.Equal(t, utils.PlatformNameToClass("Android"), "Mobile")
|
assert.Equal(t, constant.PlatformNameToClass("Android"), "Mobile")
|
||||||
assert.Equal(t, utils.PlatformNameToClass("OSX"), "PC")
|
assert.Equal(t, constant.PlatformNameToClass("OSX"), "PC")
|
||||||
assert.Equal(t, utils.PlatformNameToClass("Windows"), "PC")
|
assert.Equal(t, constant.PlatformNameToClass("Windows"), "PC")
|
||||||
assert.Equal(t, utils.PlatformNameToClass("Web"), "PC")
|
assert.Equal(t, constant.PlatformNameToClass("Web"), "PC")
|
||||||
assert.Equal(t, utils.PlatformNameToClass("MiniWeb"), "Mobile")
|
assert.Equal(t, constant.PlatformNameToClass("MiniWeb"), "Mobile")
|
||||||
assert.Equal(t, utils.PlatformNameToClass("Linux"), "PC")
|
assert.Equal(t, constant.PlatformNameToClass("Linux"), "PC")
|
||||||
|
|
||||||
assert.Equal(t, utils.PlatformNameToClass("UnknownDevice"), "")
|
assert.Equal(t, constant.PlatformNameToClass("UnknownDevice"), "")
|
||||||
assert.Equal(t, utils.PlatformNameToClass(""), "")
|
assert.Equal(t, constant.PlatformNameToClass(""), "")
|
||||||
}
|
}
|
||||||
|
@ -1,73 +1,73 @@
|
|||||||
package multi_terminal_login
|
package multi_terminal_login
|
||||||
|
|
||||||
import (
|
//
|
||||||
"Open_IM/internal/push/content_struct"
|
//import (
|
||||||
"Open_IM/internal/push/logic"
|
// "Open_IM/internal/push/content_struct"
|
||||||
"Open_IM/pkg/common/config"
|
// "Open_IM/internal/push/logic"
|
||||||
"Open_IM/pkg/common/constant"
|
// "Open_IM/pkg/common/config"
|
||||||
"Open_IM/pkg/common/db"
|
// "Open_IM/pkg/common/constant"
|
||||||
pbChat "Open_IM/pkg/proto/chat"
|
// "Open_IM/pkg/common/db"
|
||||||
"Open_IM/pkg/utils"
|
// pbChat "Open_IM/pkg/proto/chat"
|
||||||
)
|
// "Open_IM/pkg/utils"
|
||||||
|
//)
|
||||||
func MultiTerminalLoginChecker(uid, token string, platformID int32) error {
|
//
|
||||||
// 1.check userid and platform class 0 not exists and 1 exists
|
//const DayOfSecond = 24*60*60
|
||||||
existsInterface, err := db.DB.ExistsUserIDAndPlatform(uid, utils.PlatformNameToClass(utils.PlatformIDToName(platformID)))
|
//func MultiTerminalLoginChecker(uid, token string, platformID int32) error {
|
||||||
if err != nil {
|
// // 1.check userid and platform class 0 not exists and 1 exists
|
||||||
return err
|
// exists, err := db.DB.ExistsUserIDAndPlatform(uid, constant.PlatformNameToClass(constant.PlatformIDToName(platformID)))
|
||||||
}
|
// if err != nil {
|
||||||
exists := existsInterface.(int64)
|
// return err
|
||||||
//get config multi login policy
|
// }
|
||||||
if config.Config.MultiLoginPolicy.OnlyOneTerminalAccess {
|
// //get config multi login policy
|
||||||
//OnlyOneTerminalAccess policy need to check all terminal
|
// if config.Config.MultiLoginPolicy {
|
||||||
if utils.PlatformNameToClass(utils.PlatformIDToName(platformID)) == "PC" {
|
// //OnlyOneTerminalAccess policy need to check all terminal
|
||||||
existsInterface, err = db.DB.ExistsUserIDAndPlatform(uid, "Mobile")
|
// if constant.PlatformNameToClass(constant.PlatformIDToName(platformID)) == "PC" {
|
||||||
if err != nil {
|
// exists, err = db.DB.ExistsUserIDAndPlatform(uid, "Mobile")
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
} else {
|
// }
|
||||||
existsInterface, err = db.DB.ExistsUserIDAndPlatform(uid, "PC")
|
// } else {
|
||||||
if err != nil {
|
// exists, err = db.DB.ExistsUserIDAndPlatform(uid, "PC")
|
||||||
return err
|
// if err != nil {
|
||||||
}
|
// return err
|
||||||
}
|
// }
|
||||||
exists = existsInterface.(int64)
|
// }
|
||||||
if exists == 1 {
|
// if exists == 1 {
|
||||||
err := db.DB.SetUserIDAndPlatform(uid, utils.PlatformNameToClass(utils.PlatformIDToName(platformID)), token, config.Config.TokenPolicy.AccessExpire)
|
// err := db.DB.SetUserIDAndPlatform(uid, constant.PlatformNameToClass(constant.PlatformIDToName(platformID)), token, config.Config.TokenPolicy.AccessExpire*DayOfSecond)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
PushMessageToTheTerminal(uid, platformID)
|
// PushMessageToTheTerminal(uid, platformID)
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
} else if config.Config.MultiLoginPolicy.MobileAndPCTerminalAccessButOtherTerminalKickEachOther {
|
// } else if config.Config.MultiLoginPolicy.MobileAndPCTerminalAccessButOtherTerminalKickEachOther {
|
||||||
// common terminal need to kick eich other
|
// // common terminal need to kick eich other
|
||||||
if exists == 1 {
|
// if exists == 1 {
|
||||||
err := db.DB.SetUserIDAndPlatform(uid, utils.PlatformNameToClass(utils.PlatformIDToName(platformID)), token, config.Config.TokenPolicy.AccessExpire)
|
// err := db.DB.SetUserIDAndPlatform(uid, constant.PlatformNameToClass(constant.PlatformIDToName(platformID)), token, config.Config.TokenPolicy.AccessExpire*DayOfSecond)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
PushMessageToTheTerminal(uid, platformID)
|
// PushMessageToTheTerminal(uid, platformID)
|
||||||
return nil
|
// return nil
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
err = db.DB.SetUserIDAndPlatform(uid, utils.PlatformNameToClass(utils.PlatformIDToName(platformID)), token, config.Config.TokenPolicy.AccessExpire)
|
// err = db.DB.SetUserIDAndPlatform(uid, constant.PlatformNameToClass(constant.PlatformIDToName(platformID)), token, config.Config.TokenPolicy.AccessExpire*DayOfSecond)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
// }
|
||||||
PushMessageToTheTerminal(uid, platformID)
|
// PushMessageToTheTerminal(uid, platformID)
|
||||||
return nil
|
// return nil
|
||||||
}
|
//}
|
||||||
|
////
|
||||||
func PushMessageToTheTerminal(uid string, platform int32) {
|
////func PushMessageToTheTerminal(uid string, platform int32) {
|
||||||
|
////
|
||||||
logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{
|
//// logic.SendMsgByWS(&pbChat.WSToMsgSvrChatMsg{
|
||||||
SendID: uid,
|
//// SendID: uid,
|
||||||
RecvID: uid,
|
//// RecvID: uid,
|
||||||
Content: content_struct.NewContentStructString(1, "", "Your account is already logged on other terminal,please confirm"),
|
//// Content: content_struct.NewContentStructString(1, "", "Your account is already logged on other terminal,please confirm"),
|
||||||
SendTime: utils.GetCurrentTimestampBySecond(),
|
//// SendTime: utils.GetCurrentTimestampBySecond(),
|
||||||
MsgFrom: constant.SysMsgType,
|
//// MsgFrom: constant.SysMsgType,
|
||||||
ContentType: constant.KickOnlineTip,
|
//// ContentType: constant.KickOnlineTip,
|
||||||
PlatformID: platform,
|
//// PlatformID: platform,
|
||||||
})
|
//// })
|
||||||
}
|
////}
|
||||||
|
@ -0,0 +1,144 @@
|
|||||||
|
package token_verify
|
||||||
|
|
||||||
|
import (
|
||||||
|
"Open_IM/pkg/common/config"
|
||||||
|
"Open_IM/pkg/common/constant"
|
||||||
|
commonDB "Open_IM/pkg/common/db"
|
||||||
|
"Open_IM/pkg/common/log"
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//var (
|
||||||
|
// TokenExpired = errors.New("token is timed out, please log in again")
|
||||||
|
// TokenInvalid = errors.New("token has been invalidated")
|
||||||
|
// TokenNotValidYet = errors.New("token not active yet")
|
||||||
|
// TokenMalformed = errors.New("that's not even a token")
|
||||||
|
// TokenUnknown = errors.New("couldn't handle this token")
|
||||||
|
//)
|
||||||
|
|
||||||
|
type Claims struct {
|
||||||
|
UID string
|
||||||
|
Platform string //login platform
|
||||||
|
jwt.RegisteredClaims
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildClaims(uid, platform string, ttl int64) Claims {
|
||||||
|
now := time.Now()
|
||||||
|
return Claims{
|
||||||
|
UID: uid,
|
||||||
|
Platform: platform,
|
||||||
|
RegisteredClaims: jwt.RegisteredClaims{
|
||||||
|
ExpiresAt: jwt.NewNumericDate(now.Add(time.Duration(ttl*24) * time.Hour)), //Expiration time
|
||||||
|
IssuedAt: jwt.NewNumericDate(now), //Issuing time
|
||||||
|
NotBefore: jwt.NewNumericDate(now), //Begin Effective time
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateToken(userID string, platformID int32) (string, int64, error) {
|
||||||
|
claims := BuildClaims(userID, constant.PlatformIDToName(platformID), config.Config.TokenPolicy.AccessExpire)
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
tokenString, err := token.SignedString([]byte(config.Config.TokenPolicy.AccessSecret))
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
err = commonDB.DB.AddTokenFlag(userID, platformID, tokenString, constant.NormalToken)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
return tokenString, claims.ExpiresAt.Time.Unix(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func secret() jwt.Keyfunc {
|
||||||
|
return func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte(config.Config.TokenPolicy.AccessSecret), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getClaimFromToken(tokensString string) (*Claims, error) {
|
||||||
|
token, err := jwt.ParseWithClaims(tokensString, &Claims{}, secret())
|
||||||
|
if err != nil {
|
||||||
|
if ve, ok := err.(*jwt.ValidationError); ok {
|
||||||
|
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
|
||||||
|
return nil, &constant.ErrTokenMalformed
|
||||||
|
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
|
||||||
|
return nil, &constant.ErrTokenExpired
|
||||||
|
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
|
||||||
|
return nil, &constant.ErrTokenNotValidYet
|
||||||
|
} else {
|
||||||
|
return nil, &constant.ErrTokenUnknown
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, &constant.ErrTokenNotValidYet
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if claims, ok := token.Claims.(*Claims); ok && token.Valid {
|
||||||
|
return claims, nil
|
||||||
|
}
|
||||||
|
return nil, &constant.ErrTokenNotValidYet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseToken(tokensString string) (claims *Claims, err error) {
|
||||||
|
//根据token的算法本身做出的有效性检验
|
||||||
|
claims, err = getClaimFromToken(tokensString)
|
||||||
|
if err != nil {
|
||||||
|
log.NewError("", "token validate err", err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//根据redis做出的有效性检验
|
||||||
|
m, err := commonDB.DB.GetTokenMapByUidPid(claims.UID, claims.Platform)
|
||||||
|
if err != nil {
|
||||||
|
log.NewError("", "get token from redis err", err.Error())
|
||||||
|
return nil, &constant.ErrTokenInvalid
|
||||||
|
}
|
||||||
|
if m == nil {
|
||||||
|
log.NewError("", "get token from redis err", "m is nil")
|
||||||
|
return nil, &constant.ErrTokenInvalid
|
||||||
|
}
|
||||||
|
if v, ok := m[tokensString]; ok {
|
||||||
|
switch v {
|
||||||
|
case constant.NormalToken:
|
||||||
|
return claims, nil
|
||||||
|
case constant.InValidToken:
|
||||||
|
return nil, &constant.ErrTokenInvalid
|
||||||
|
case constant.KickedToken:
|
||||||
|
return nil, &constant.ErrTokenInvalid
|
||||||
|
case constant.ExpiredToken:
|
||||||
|
return nil, &constant.ErrTokenExpired
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//func MakeTheTokenInvalid(currentClaims *Claims, platformClass string) (bool, error) {
|
||||||
|
// storedRedisTokenInterface, err := db.DB.GetPlatformToken(currentClaims.UID, platformClass)
|
||||||
|
// if err != nil {
|
||||||
|
// return false, err
|
||||||
|
// }
|
||||||
|
// storedRedisPlatformClaims, err := ParseRedisInterfaceToken(storedRedisTokenInterface)
|
||||||
|
// if err != nil {
|
||||||
|
// return false, err
|
||||||
|
// }
|
||||||
|
// //if issue time less than redis token then make this token invalid
|
||||||
|
// if currentClaims.IssuedAt.Time.Unix() < storedRedisPlatformClaims.IssuedAt.Time.Unix() {
|
||||||
|
// return true, constant.TokenInvalid
|
||||||
|
// }
|
||||||
|
// return false, nil
|
||||||
|
//}
|
||||||
|
|
||||||
|
func ParseRedisInterfaceToken(redisToken interface{}) (*Claims, error) {
|
||||||
|
return getClaimFromToken(string(redisToken.([]uint8)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//Validation token, false means failure, true means successful verification
|
||||||
|
func VerifyToken(token, uid string) (bool, error) {
|
||||||
|
claims, err := ParseToken(token)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if claims.UID != uid {
|
||||||
|
return false, &constant.ErrTokenUnknown
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
@ -1,153 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"Open_IM/pkg/common/config"
|
|
||||||
"Open_IM/pkg/common/db"
|
|
||||||
"errors"
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
TokenExpired = errors.New("token is timed out, please log in again")
|
|
||||||
TokenInvalid = errors.New("token has been invalidated")
|
|
||||||
TokenNotValidYet = errors.New("token not active yet")
|
|
||||||
TokenMalformed = errors.New("that's not even a token")
|
|
||||||
TokenUnknown = errors.New("couldn't handle this token")
|
|
||||||
)
|
|
||||||
|
|
||||||
type Claims struct {
|
|
||||||
UID string
|
|
||||||
Platform string //login platform
|
|
||||||
jwt.RegisteredClaims
|
|
||||||
}
|
|
||||||
|
|
||||||
func BuildClaims(uid, platform string, ttl int64) Claims {
|
|
||||||
now := time.Now()
|
|
||||||
return Claims{
|
|
||||||
UID: uid,
|
|
||||||
Platform: platform,
|
|
||||||
RegisteredClaims: jwt.RegisteredClaims{
|
|
||||||
ExpiresAt: jwt.NewNumericDate(now.Add(time.Duration(ttl*24) * time.Hour)), //Expiration time
|
|
||||||
IssuedAt: jwt.NewNumericDate(now), //Issuing time
|
|
||||||
NotBefore: jwt.NewNumericDate(now), //Begin Effective time
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateToken(userID string, platform int32) (string, int64, error) {
|
|
||||||
claims := BuildClaims(userID, PlatformIDToName(platform), config.Config.TokenPolicy.AccessExpire)
|
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
||||||
tokenString, err := token.SignedString([]byte(config.Config.TokenPolicy.AccessSecret))
|
|
||||||
|
|
||||||
return tokenString, claims.ExpiresAt.Time.Unix(), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func secret() jwt.Keyfunc {
|
|
||||||
return func(token *jwt.Token) (interface{}, error) {
|
|
||||||
return []byte(config.Config.TokenPolicy.AccessSecret), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getClaimFromToken(tokensString string) (*Claims, error) {
|
|
||||||
token, err := jwt.ParseWithClaims(tokensString, &Claims{}, secret())
|
|
||||||
if err != nil {
|
|
||||||
if ve, ok := err.(*jwt.ValidationError); ok {
|
|
||||||
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
|
|
||||||
return nil, TokenMalformed
|
|
||||||
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
|
|
||||||
return nil, TokenExpired
|
|
||||||
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
|
|
||||||
return nil, TokenNotValidYet
|
|
||||||
} else {
|
|
||||||
return nil, TokenUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if claims, ok := token.Claims.(*Claims); ok && token.Valid {
|
|
||||||
return claims, nil
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseToken(tokensString string) (claims *Claims, err error) {
|
|
||||||
claims, err = getClaimFromToken(tokensString)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1.check userid and platform class 0 not exists and 1 exists
|
|
||||||
existsInterface, err := db.DB.ExistsUserIDAndPlatform(claims.UID, Platform2class[claims.Platform])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
exists := existsInterface.(int64)
|
|
||||||
//get config multi login policy
|
|
||||||
if config.Config.MultiLoginPolicy.OnlyOneTerminalAccess {
|
|
||||||
//OnlyOneTerminalAccess policy need to check all terminal
|
|
||||||
//When only one end is allowed to log in, there is a situation that needs to be paid attention to. After PC login,
|
|
||||||
//mobile login should check two platform times. One of them is less than the redis storage time, which is the invalid token.
|
|
||||||
platform := "PC"
|
|
||||||
if Platform2class[claims.Platform] == "PC" {
|
|
||||||
platform = "Mobile"
|
|
||||||
}
|
|
||||||
|
|
||||||
existsInterface, err = db.DB.ExistsUserIDAndPlatform(claims.UID, platform)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
exists = existsInterface.(int64)
|
|
||||||
if exists == 1 {
|
|
||||||
res, err := MakeTheTokenInvalid(claims, platform)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if res {
|
|
||||||
return nil, TokenInvalid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// config.Config.MultiLoginPolicy.MobileAndPCTerminalAccessButOtherTerminalKickEachOther == true
|
|
||||||
// or PC/Mobile validate success
|
|
||||||
// final check
|
|
||||||
if exists == 1 {
|
|
||||||
res, err := MakeTheTokenInvalid(claims, Platform2class[claims.Platform])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if res {
|
|
||||||
return nil, TokenInvalid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return claims, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeTheTokenInvalid(currentClaims *Claims, platformClass string) (bool, error) {
|
|
||||||
storedRedisTokenInterface, err := db.DB.GetPlatformToken(currentClaims.UID, platformClass)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
storedRedisPlatformClaims, err := ParseRedisInterfaceToken(storedRedisTokenInterface)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
//if issue time less than redis token then make this token invalid
|
|
||||||
if currentClaims.IssuedAt.Time.Unix() < storedRedisPlatformClaims.IssuedAt.Time.Unix() {
|
|
||||||
return true, TokenInvalid
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseRedisInterfaceToken(redisToken interface{}) (*Claims, error) {
|
|
||||||
return getClaimFromToken(string(redisToken.([]uint8)))
|
|
||||||
}
|
|
||||||
|
|
||||||
//Validation token, false means failure, true means successful verification
|
|
||||||
func VerifyToken(token, uid string) bool {
|
|
||||||
claims, err := ParseToken(token)
|
|
||||||
if err != nil || claims.UID != uid {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
Loading…
Reference in new issue