From 4f041b81b8975c4f9dc88fb282b8c572dc6321f6 Mon Sep 17 00:00:00 2001 From: dragove Date: Tue, 29 Oct 2024 22:46:06 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E4=BF=AE=E6=94=B9=E6=97=B6=E9=97=B4=E7=94=A8?= =?UTF-8?q?=E4=BB=A5=E4=BF=AE=E5=A4=8Drefresh=E6=97=B6=E6=97=A0=E4=BB=BB?= =?UTF-8?q?=E4=BD=95=E9=99=90=E5=88=B6=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E9=99=90=E5=88=B6=E5=AF=86=E7=A0=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E9=A2=91=E7=8E=87=E3=80=82=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=80=BB=E8=BE=91refresh=E6=97=B6=E5=A6=82=E6=9E=9C=E7=AD=BE?= =?UTF-8?q?=E5=8F=91=E6=97=B6=E9=97=B4=E4=B8=8E=E5=BD=93=E5=89=8D=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E7=9B=B8=E8=BF=91=E5=88=99=E8=BF=94=E5=9B=9E=E6=97=A7?= =?UTF-8?q?token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../maa/backend/repository/entity/MaaUser.kt | 3 ++- .../plus/maa/backend/service/UserService.kt | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/plus/maa/backend/repository/entity/MaaUser.kt b/src/main/kotlin/plus/maa/backend/repository/entity/MaaUser.kt index 170667fa..8a7da3a0 100644 --- a/src/main/kotlin/plus/maa/backend/repository/entity/MaaUser.kt +++ b/src/main/kotlin/plus/maa/backend/repository/entity/MaaUser.kt @@ -6,6 +6,7 @@ import org.springframework.data.annotation.Transient import org.springframework.data.mongodb.core.index.Indexed import org.springframework.data.mongodb.core.mapping.Document import java.io.Serializable +import java.time.Instant /** * @author AnselYuki @@ -20,7 +21,7 @@ data class MaaUser( val email: String, var password: String, var status: Int = 0, - var refreshJwtIds: MutableList = ArrayList(), + var pwdUpdateTime: Instant = Instant.MIN, ) : Serializable { companion object { diff --git a/src/main/kotlin/plus/maa/backend/service/UserService.kt b/src/main/kotlin/plus/maa/backend/service/UserService.kt index e1965fa9..c869086f 100644 --- a/src/main/kotlin/plus/maa/backend/service/UserService.kt +++ b/src/main/kotlin/plus/maa/backend/service/UserService.kt @@ -18,6 +18,8 @@ import plus.maa.backend.repository.entity.MaaUser import plus.maa.backend.service.jwt.JwtExpiredException import plus.maa.backend.service.jwt.JwtInvalidException import plus.maa.backend.service.jwt.JwtService +import java.time.Instant +import java.time.temporal.ChronoUnit /** * @author AnselYuki @@ -76,6 +78,10 @@ class UserService( check(passwordEncoder.matches(originPassword, maaUser.password)) { "原密码错误" } + // 通过原密码修改密码不能过于频繁 + check(ChronoUnit.MINUTES.between(maaUser.pwdUpdateTime, Instant.now()) >= 10L) { + "密码修改过于频繁" + } } // 修改密码的逻辑,应当使用与 authentication provider 一致的编码器 maaUser.password = passwordEncoder.encode(rawPassword) @@ -83,7 +89,7 @@ class UserService( if (maaUser.status == 0) { maaUser.status = 1 } - maaUser.refreshJwtIds = ArrayList() + maaUser.pwdUpdateTime = Instant.now() userRepository.save(maaUser) } @@ -135,7 +141,16 @@ class UserService( val userId = old.subject val user = userRepository.findById(userId).orElseThrow() - val refreshToken = jwtService.issueRefreshToken(userId, null) + if (old.notBefore.isBefore(user.pwdUpdateTime)) { + throw MaaResultException(401, "invalid token") + } + + // 刚签发不久的 refreshToken 重新使用 + val refreshToken = if (ChronoUnit.MINUTES.between(old.issuedAt, Instant.now()) < 5) { + old + } else { + jwtService.issueRefreshToken(userId, null) + } val authorities = userDetailService.collectAuthoritiesFor(user) val authToken = jwtService.issueAuthToken(userId, null, authorities)