Offline user when change password

This commit is contained in:
2023-12-01 15:38:36 +08:00
parent cdb6339787
commit 8dc5533473
5 changed files with 32 additions and 7 deletions

View File

@@ -36,11 +36,16 @@ class JwtAuthenticationTokenFilter(private val redisUtil: RedisUtil) : OncePerRe
val token = WebUtil.getToken(tokenWithPrefix) val token = WebUtil.getToken(tokenWithPrefix)
JwtUtil.parseJwt(token) JwtUtil.parseJwt(token)
val redisKey = "${SecurityProperties.jwtIssuer}_login:" + token val redisKeyPattern = "${SecurityProperties.jwtIssuer}_login_*:" + token
val loginUser = redisUtil.getObject<LoginUser>(redisKey) val redisKeys = redisUtil.keys(redisKeyPattern)
if (redisKeys.isEmpty()) {
throw TokenHasExpiredException()
}
val loginUser = redisUtil.getObject<LoginUser>(redisKeys.first())
loginUser ?: let { throw TokenHasExpiredException() } loginUser ?: let { throw TokenHasExpiredException() }
redisUtil.setExpire(redisKey, SecurityProperties.redisTtl, SecurityProperties.redisTtlUnit) redisUtil.setExpire(redisKeys.first(), SecurityProperties.redisTtl, SecurityProperties.redisTtlUnit)
val authenticationToken = UsernamePasswordAuthenticationToken(loginUser, null, loginUser.authorities) val authenticationToken = UsernamePasswordAuthenticationToken(loginUser, null, loginUser.authorities)
SecurityContextHolder.getContext().authentication = authenticationToken SecurityContextHolder.getContext().authentication = authenticationToken

View File

@@ -1,8 +1,9 @@
package top.fatweb.api.service.api.v1 package top.fatweb.api.service.api.v1.impl
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import top.fatweb.api.param.api.v1.avatar.AvatarBaseParam import top.fatweb.api.param.api.v1.avatar.AvatarBaseParam
import top.fatweb.api.param.api.v1.avatar.AvatarGitHubParam import top.fatweb.api.param.api.v1.avatar.AvatarGitHubParam
import top.fatweb.api.service.api.v1.IAvatarService
import top.fatweb.api.util.NumberUtil import top.fatweb.api.util.NumberUtil
import top.fatweb.api.vo.api.v1.avatar.AvatarBase64Vo import top.fatweb.api.vo.api.v1.avatar.AvatarBase64Vo
import top.fatweb.avatargenerator.GitHubAvatar import top.fatweb.avatargenerator.GitHubAvatar

View File

@@ -60,7 +60,7 @@ class AuthenticationServiceImpl(
throw RuntimeException("Login failed") throw RuntimeException("Login failed")
} }
val redisKey = "${SecurityProperties.jwtIssuer}_login:" + jwt val redisKey = "${SecurityProperties.jwtIssuer}_login_${userId}:" + jwt
redisUtil.setObject(redisKey, loginUser, SecurityProperties.redisTtl, SecurityProperties.redisTtlUnit) redisUtil.setObject(redisKey, loginUser, SecurityProperties.redisTtl, SecurityProperties.redisTtlUnit)
return LoginVo(jwt, loginUser.user.currentLoginTime, loginUser.user.currentLoginIp) return LoginVo(jwt, loginUser.user.currentLoginTime, loginUser.user.currentLoginIp)
@@ -71,7 +71,7 @@ class AuthenticationServiceImpl(
override fun renewToken(token: String): TokenVo { override fun renewToken(token: String): TokenVo {
val loginUser = WebUtil.getLoginUser() ?: let { throw TokenHasExpiredException() } val loginUser = WebUtil.getLoginUser() ?: let { throw TokenHasExpiredException() }
val oldRedisKey = "${SecurityProperties.jwtIssuer}_login:" + token val oldRedisKey = "${SecurityProperties.jwtIssuer}_login_${loginUser.user.id}:" + token
redisUtil.delObject(oldRedisKey) redisUtil.delObject(oldRedisKey)
val jwt = JwtUtil.createJwt(WebUtil.getLoginUserId().toString()) val jwt = JwtUtil.createJwt(WebUtil.getLoginUserId().toString())
@@ -79,7 +79,7 @@ class AuthenticationServiceImpl(
throw RuntimeException("Login failed") throw RuntimeException("Login failed")
} }
val redisKey = "${SecurityProperties.jwtIssuer}_login:" + jwt val redisKey = "${SecurityProperties.jwtIssuer}_login_${loginUser.user.id}:" + jwt
redisUtil.setObject( redisUtil.setObject(
redisKey, loginUser, SecurityProperties.redisTtl, SecurityProperties.redisTtlUnit redisKey, loginUser, SecurityProperties.redisTtl, SecurityProperties.redisTtlUnit
) )

View File

@@ -18,6 +18,7 @@ import top.fatweb.api.mapper.permission.UserMapper
import top.fatweb.api.param.permission.user.* import top.fatweb.api.param.permission.user.*
import top.fatweb.api.service.permission.* import top.fatweb.api.service.permission.*
import top.fatweb.api.util.PageUtil import top.fatweb.api.util.PageUtil
import top.fatweb.api.util.RedisUtil
import top.fatweb.api.util.StrUtil import top.fatweb.api.util.StrUtil
import top.fatweb.api.util.WebUtil import top.fatweb.api.util.WebUtil
import top.fatweb.api.vo.PageVo import top.fatweb.api.vo.PageVo
@@ -35,6 +36,7 @@ import java.time.ZoneOffset
@Service @Service
class UserServiceImpl( class UserServiceImpl(
private val passwordEncoder: PasswordEncoder, private val passwordEncoder: PasswordEncoder,
private val redisUtil: RedisUtil,
private val userInfoService: IUserInfoService, private val userInfoService: IUserInfoService,
private val moduleService: IModuleService, private val moduleService: IModuleService,
private val menuService: IMenuService, private val menuService: IMenuService,
@@ -193,6 +195,8 @@ class UserServiceImpl(
}) })
} }
userUpdateParam.id?.let { WebUtil.offlineUser(redisUtil, it) }
return UserConverter.userToUserWithRoleInfoVo(user) return UserConverter.userToUserWithRoleInfoVo(user)
} }
@@ -209,11 +213,14 @@ class UserServiceImpl(
.set(User::updateTime, LocalDateTime.now(ZoneOffset.UTC)) .set(User::updateTime, LocalDateTime.now(ZoneOffset.UTC))
this.update(wrapper) this.update(wrapper)
userChangePasswordParam.id?.let { WebUtil.offlineUser(redisUtil, it) }
} ?: let { } ?: let {
throw NoRecordFoundException() throw NoRecordFoundException()
} }
} }
@Transactional
override fun deleteOne(id: Long) { override fun deleteOne(id: Long) {
if (id == 0L) { if (id == 0L) {
return return
@@ -222,6 +229,7 @@ class UserServiceImpl(
this.delete(UserDeleteParam(listOf(id))) this.delete(UserDeleteParam(listOf(id)))
} }
@Transactional
override fun delete(userDeleteParam: UserDeleteParam) { override fun delete(userDeleteParam: UserDeleteParam) {
val ids = userDeleteParam.ids.filter { it != 0L } val ids = userDeleteParam.ids.filter { it != 0L }
if (ids.isEmpty()) { if (ids.isEmpty()) {
@@ -232,5 +240,7 @@ class UserServiceImpl(
userInfoService.remove(KtQueryWrapper(UserInfo()).`in`(UserInfo::userId, ids)) userInfoService.remove(KtQueryWrapper(UserInfo()).`in`(UserInfo::userId, ids))
userRoleService.remove(KtQueryWrapper(UserRole()).`in`(UserRole::userId, ids)) userRoleService.remove(KtQueryWrapper(UserRole()).`in`(UserRole::userId, ids))
userGroupService.remove(KtQueryWrapper(UserGroup()).`in`(UserGroup::userId, ids)) userGroupService.remove(KtQueryWrapper(UserGroup()).`in`(UserGroup::userId, ids))
WebUtil.offlineUser(redisUtil, *ids.toLongArray())
} }
} }

View File

@@ -22,4 +22,13 @@ object WebUtil {
fun getToken(tokenWithPrefix: String) = tokenWithPrefix.removePrefix(SecurityProperties.tokenPrefix) fun getToken(tokenWithPrefix: String) = tokenWithPrefix.removePrefix(SecurityProperties.tokenPrefix)
fun getToken(request: HttpServletRequest) = getToken(request.getHeader(SecurityProperties.headerString)) fun getToken(request: HttpServletRequest) = getToken(request.getHeader(SecurityProperties.headerString))
fun offlineUser(redisUtil: RedisUtil, vararg userIds: Long) {
val keys = HashSet<String>()
userIds.forEach {
keys.addAll(redisUtil.keys("${SecurityProperties.jwtIssuer}_login_${it}:*"))
}
redisUtil.delObject(keys)
}
} }