Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cnooc_zydeepen-cggl_expert-manage-miniapp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙德龙
cnooc_zydeepen-cggl_expert-manage-miniapp
Commits
20ca8a31
Commit
20ca8a31
authored
Nov 14, 2025
by
weisong
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
http://git.gdatac.com/sundelong/cnooc_zydeepen-cggl_expert-manage-miniapp
parents
525f5bb3
c9be99c8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
111 additions
and
0 deletions
+111
-0
src/main/java/com/cnooc/expert/auth/service/AccountLockService.java
+110
-0
src/main/java/com/cnooc/expert/common/exception/GlobalErrorCodeConstants.java
+1
-0
No files found.
src/main/java/com/cnooc/expert/auth/service/AccountLockService.java
0 → 100644
View file @
20ca8a31
package
com
.
cnooc
.
expert
.
auth
.
service
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.stereotype.Service
;
import
java.time.LocalDateTime
;
import
java.util.concurrent.TimeUnit
;
@Service
public
class
AccountLockService
{
@Autowired
private
StringRedisTemplate
redisTemplate
;
// 锁定策略:3次错误 -> 10分钟,4次错误 -> 30分钟,5次及以上错误 -> 1小时
private
static
final
int
[]
LOCK_DURATIONS
=
{
10
,
30
,
60
};
// 分钟
private
static
final
int
MAX_ATTEMPTS
=
3
;
private
String
getLockKey
(
String
account
)
{
return
"login:lock:"
+
account
;
}
private
String
getAttemptKey
(
String
account
)
{
return
"login:attempt:"
+
account
;
}
private
int
calculateLockMinutes
(
long
failureCount
)
{
if
(
failureCount
<
MAX_ATTEMPTS
)
{
return
0
;
// 不锁定
}
else
if
(
failureCount
==
MAX_ATTEMPTS
)
{
return
LOCK_DURATIONS
[
0
];
// 10分钟
}
else
if
(
failureCount
==
MAX_ATTEMPTS
+
1
)
{
return
LOCK_DURATIONS
[
1
];
// 30分钟
}
else
{
return
LOCK_DURATIONS
[
2
];
// 60分钟
}
}
private
void
lockAccount
(
String
account
,
int
lockMinutes
)
{
String
lockKey
=
getLockKey
(
account
);
String
lockValue
=
LocalDateTime
.
now
().
toString
()
+
"|"
+
lockMinutes
;
redisTemplate
.
opsForValue
().
set
(
lockKey
,
lockValue
,
lockMinutes
,
TimeUnit
.
MINUTES
);
//这个超时时间需要考虑一下
}
/**
* 手动解锁账号
*/
public
void
unlockAccount
(
String
account
)
{
String
attemptKey
=
getAttemptKey
(
account
);
String
lockKey
=
getLockKey
(
account
);
redisTemplate
.
delete
(
attemptKey
);
redisTemplate
.
delete
(
lockKey
);
}
/**
* 处理登录成功(重置失败计数和锁定)
*/
public
void
handleLoginSuccess
(
String
account
)
{
String
attemptKey
=
getAttemptKey
(
account
);
String
lockKey
=
getLockKey
(
account
);
redisTemplate
.
delete
(
attemptKey
);
redisTemplate
.
delete
(
lockKey
);
}
/**
* 处理登录失败
*/
public
void
handleLoginFailure
(
String
account
)
{
String
attemptKey
=
getAttemptKey
(
account
);
String
lockKey
=
getLockKey
(
account
);
// 如果已经锁定,不再增加计数
if
(
Boolean
.
TRUE
.
equals
(
redisTemplate
.
hasKey
(
lockKey
)))
{
return
;
}
// 增加失败计数
//long failureCount = jedis.incr(attemptKey);
String
failureCountStr
=
redisTemplate
.
opsForValue
().
get
(
attemptKey
)!=
null
?
redisTemplate
.
opsForValue
().
get
(
attemptKey
).
toString
():
"0"
;
long
failureCount
=
Long
.
parseLong
(
failureCountStr
)+
1
;
redisTemplate
.
opsForValue
().
set
(
attemptKey
,
String
.
valueOf
(
failureCount
));
// 设置计数过期时间(避免无限增长)
if
(
failureCount
==
1
)
{
redisTemplate
.
expire
(
attemptKey
,
24
*
60
,
TimeUnit
.
MINUTES
);
// 24小时过期
}
// 根据失败次数确定锁定时间
int
lockMinutes
=
calculateLockMinutes
(
failureCount
);
if
(
lockMinutes
>
0
)
{
lockAccount
(
account
,
lockMinutes
);
// 重置失败计数(锁定期间不需要继续计数)
redisTemplate
.
delete
(
attemptKey
);
}
}
/**
* 检查账号是否被锁定
*/
public
boolean
isAccountLocked
(
String
account
)
{
String
lockKey
=
getLockKey
(
account
);
return
Boolean
.
TRUE
.
equals
(
redisTemplate
.
hasKey
(
lockKey
));
}
/**
* 获取锁定剩余时间
*/
public
long
getLockRemainingTime
(
String
account
)
{
String
lockKey
=
getLockKey
(
account
);
boolean
isExist
=
Boolean
.
TRUE
.
equals
(
redisTemplate
.
hasKey
(
lockKey
));
if
(
isExist
){
return
redisTemplate
.
getExpire
(
lockKey
,
TimeUnit
.
MINUTES
);
}
else
{
return
0
;
}
}
}
src/main/java/com/cnooc/expert/common/exception/GlobalErrorCodeConstants.java
View file @
20ca8a31
...
...
@@ -26,6 +26,7 @@ public interface GlobalErrorCodeConstants {
ErrorCode
PASSWORD_ERROR
=
new
ErrorCode
(
2003
,
"密码错误"
);
ErrorCode
USER_DISABLED
=
new
ErrorCode
(
2004
,
"用户已被禁用"
);
ErrorCode
PASSWORD_NOT_EXIST
=
new
ErrorCode
(
2005
,
"密码不存在,请先重置密码"
);
ErrorCode
USER_LOCKED
=
new
ErrorCode
(
2006
,
"账号已锁定"
);
// ========== 参数校验错误 (3000-3999) ==========
ErrorCode
PARAM_REQUIRED
=
new
ErrorCode
(
3001
,
"必填字段不能为空"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment