feat: add DeviceMaxLoginCount

This commit is contained in:
weloe
2023-10-22 05:02:08 +08:00
parent d89e273487
commit bb1845fd3c
2 changed files with 66 additions and 18 deletions

View File

@@ -25,6 +25,8 @@ type TokenConfig struct {
// If (IsConcurrent == true && IsShare == false), support MaxLoginCount
// If IsConcurrent == -1, do not need to check loginCount
MaxLoginCount int16
// Maximum number of logins per device
DeviceMaxLoginCount int16
// Read token method
// Set to true to read token from these method before login.
@@ -62,6 +64,7 @@ func DefaultTokenConfig() *TokenConfig {
IsConcurrent: true,
IsShare: true,
MaxLoginCount: 12,
DeviceMaxLoginCount: 12,
IsReadBody: true,
IsReadHeader: true,
IsReadCookie: true,

View File

@@ -202,7 +202,7 @@ func (e *Enforcer) LoginByModel(id string, loginModel *model.Login, ctx ctx.Cont
// allocate token
tokenValue, err = e.createLoginToken(id, loginModel)
device := loginModel.Device
if err != nil {
return "", err
}
@@ -213,7 +213,7 @@ func (e *Enforcer) LoginByModel(id string, loginModel *model.Login, ctx ctx.Cont
}
session.AddTokenSign(&model.TokenSign{
Value: tokenValue,
Device: loginModel.Device,
Device: device,
})
timeout := loginModel.Timeout
@@ -237,7 +237,7 @@ func (e *Enforcer) LoginByModel(id string, loginModel *model.Login, ctx ctx.Cont
// called watcher
m := &model.Login{
Device: loginModel.Device,
Device: device,
IsLastingCookie: loginModel.IsLastingCookie,
Timeout: timeout,
JwtData: loginModel.JwtData,
@@ -252,11 +252,53 @@ func (e *Enforcer) LoginByModel(id string, loginModel *model.Login, ctx ctx.Cont
e.watcher.Login(e.loginType, id, tokenValue, m)
}
// if login success check it
if tokenConfig.IsConcurrent && !tokenConfig.IsShare {
if device != "" && tokenConfig.DeviceMaxLoginCount != -1 {
if session = e.GetSession(id); session != nil {
// get by login device
tokenSignList := session.GetFilterTokenSign(device)
if tokenSignList.Len() <= int(tokenConfig.DeviceMaxLoginCount) {
return tokenValue, nil
}
// if loginCount > maxLoginCount, logout account until single device Login count is equal to DeviceMaxLoginCount
for element := tokenSignList.Front(); element != nil; element = element.Next() {
if tokenSign, ok := element.Value.(*model.TokenSign); ok {
if session.TokenSignSize() > int(tokenConfig.DeviceMaxLoginCount) {
// delete tokenSign
tokenSignValue := tokenSign.Value
session.RemoveTokenSign(tokenSignValue)
err = e.UpdateSession(id, session)
if err != nil {
return "", err
}
// delete token-id
err = e.deleteIdByToken(tokenSignValue)
if err != nil {
return "", err
}
e.logger.Logout(e.loginType, id, tokenSignValue)
if e.watcher != nil {
e.watcher.Logout(e.loginType, id, tokenSignValue)
}
}
}
}
// check TokenSignList length, if length == 0, delete this session
if session != nil && session.TokenSignSize() == 0 {
err = e.DeleteSession(id)
if err != nil {
return "", err
}
}
}
}
// check if the number of sessions for this account exceeds the maximum limit.
if tokenConfig.MaxLoginCount != -1 {
if session = e.GetSession(id); session != nil {
if session.TokenSignSize() <= int(tokenConfig.MaxLoginCount) {
return tokenValue, nil
}
// logout account until loginCount == maxLoginCount if loginCount > maxLoginCount
for _, tokenSign := range session.TokenSignList {
if session.TokenSignSize() > int(tokenConfig.MaxLoginCount) {
@@ -272,6 +314,11 @@ func (e *Enforcer) LoginByModel(id string, loginModel *model.Login, ctx ctx.Cont
if err != nil {
return "", err
}
e.logger.Logout(e.loginType, id, tokenSignValue)
if e.watcher != nil {
e.watcher.Logout(e.loginType, id, tokenSignValue)
}
}
}
@@ -285,8 +332,6 @@ func (e *Enforcer) LoginByModel(id string, loginModel *model.Login, ctx ctx.Cont
}
}
}
return tokenValue, nil
}