Optimize code
This commit is contained in:
@@ -4,31 +4,50 @@ import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
|
|||||||
import jakarta.annotation.PostConstruct
|
import jakarta.annotation.PostConstruct
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.annotation.DependsOn
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import top.fatweb.api.entity.permission.User
|
import top.fatweb.api.entity.permission.User
|
||||||
|
import top.fatweb.api.entity.permission.UserInfo
|
||||||
|
import top.fatweb.api.properties.AdminProperties
|
||||||
|
import top.fatweb.api.service.permission.IUserInfoService
|
||||||
import top.fatweb.api.service.permission.IUserService
|
import top.fatweb.api.service.permission.IUserService
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
@DependsOn("adminProperties")
|
||||||
@Component
|
@Component
|
||||||
class InitConfig(
|
class InitConfig(
|
||||||
private val userService: IUserService, private val passwordEncoder: PasswordEncoder
|
private val userService: IUserService,
|
||||||
|
private val userInfoService: IUserInfoService,
|
||||||
|
private val passwordEncoder: PasswordEncoder
|
||||||
) {
|
) {
|
||||||
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
fun init() {
|
fun init() {
|
||||||
if (!userService.exists(KtQueryWrapper(User()).eq(User::id, 0))) {
|
if (!userService.exists(KtQueryWrapper(User()).eq(User::id, 0))) {
|
||||||
val rawPassword = getRandPassword(10)
|
userInfoService.remove(KtQueryWrapper(UserInfo()).eq(UserInfo::userId, 0))
|
||||||
|
|
||||||
|
val rawPassword = AdminProperties.password ?: let {
|
||||||
|
logger.warn("No default administrator password is set, a randomly generated password will be used")
|
||||||
|
getRandPassword(10)
|
||||||
|
}
|
||||||
val encodedPassword = passwordEncoder.encode(rawPassword)
|
val encodedPassword = passwordEncoder.encode(rawPassword)
|
||||||
|
|
||||||
val user = User().apply {
|
val user = User().apply {
|
||||||
id = 0
|
id = 0
|
||||||
username = "admin"
|
username = AdminProperties.username
|
||||||
password = encodedPassword
|
password = encodedPassword
|
||||||
locking = 0
|
locking = 0
|
||||||
enable = 1
|
enable = 1
|
||||||
}
|
}
|
||||||
if (userService.save(user)) {
|
val userInfo = UserInfo().apply {
|
||||||
|
userId = 0
|
||||||
|
nickName = AdminProperties.nickName
|
||||||
|
email = AdminProperties.email
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userService.save(user) && userInfoService.save(userInfo)) {
|
||||||
logger.warn("First startup, create administrator - username: admin, password: $rawPassword")
|
logger.warn("First startup, create administrator - username: admin, password: $rawPassword")
|
||||||
logger.warn("This information will only be shown once. Please change your password promptly after logging in.")
|
logger.warn("This information will only be shown once. Please change your password promptly after logging in.")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import io.swagger.v3.oas.models.info.Contact
|
|||||||
import io.swagger.v3.oas.models.info.Info
|
import io.swagger.v3.oas.models.info.Info
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import top.fatweb.api.constant.ServerConstants
|
import top.fatweb.api.properties.ServerProperties
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
class SwaggerConfig {
|
class SwaggerConfig {
|
||||||
@@ -16,7 +16,7 @@ class SwaggerConfig {
|
|||||||
return OpenAPI().info(
|
return OpenAPI().info(
|
||||||
Info().title("FatWeb API 文档").description("FatWeb 后端 API 文档,包含各个 Controller 调用信息")
|
Info().title("FatWeb API 文档").description("FatWeb 后端 API 文档,包含各个 Controller 调用信息")
|
||||||
.contact(contact).version(
|
.contact(contact).version(
|
||||||
ServerConstants.version
|
ServerProperties.version
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import org.springframework.web.bind.annotation.GetMapping
|
|||||||
import org.springframework.web.bind.annotation.PostMapping
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import top.fatweb.api.converter.UserConverter
|
import top.fatweb.api.converter.permission.UserConverter
|
||||||
import top.fatweb.api.entity.common.ResponseCode
|
import top.fatweb.api.entity.common.ResponseCode
|
||||||
import top.fatweb.api.entity.common.ResponseResult
|
import top.fatweb.api.entity.common.ResponseResult
|
||||||
import top.fatweb.api.param.authentication.LoginParam
|
import top.fatweb.api.param.authentication.LoginParam
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package top.fatweb.api.controller.permission
|
|||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import top.fatweb.api.converter.UserConverter
|
import top.fatweb.api.converter.permission.UserConverter
|
||||||
import top.fatweb.api.entity.common.ResponseResult
|
import top.fatweb.api.entity.common.ResponseResult
|
||||||
import top.fatweb.api.service.permission.IUserService
|
import top.fatweb.api.service.permission.IUserService
|
||||||
import top.fatweb.api.vo.authentication.UserWithInfoVo
|
import top.fatweb.api.vo.permission.UserWithInfoVo
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.GetMapping
|
|||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
import top.fatweb.api.converter.SysLogConverter
|
import top.fatweb.api.converter.system.SysLogConverter
|
||||||
import top.fatweb.api.entity.common.ResponseCode
|
import top.fatweb.api.entity.common.ResponseCode
|
||||||
import top.fatweb.api.entity.common.ResponseResult
|
import top.fatweb.api.entity.common.ResponseResult
|
||||||
import top.fatweb.api.param.system.SysLogGetParam
|
import top.fatweb.api.param.system.SysLogGetParam
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package top.fatweb.api.converter
|
package top.fatweb.api.converter.permission
|
||||||
|
|
||||||
import top.fatweb.api.entity.permission.User
|
import top.fatweb.api.entity.permission.User
|
||||||
import top.fatweb.api.param.authentication.LoginParam
|
import top.fatweb.api.param.authentication.LoginParam
|
||||||
import top.fatweb.api.vo.authentication.*
|
import top.fatweb.api.vo.permission.*
|
||||||
|
|
||||||
object UserConverter {
|
object UserConverter {
|
||||||
fun loginParamToUser(loginParam: LoginParam): User {
|
fun loginParamToUser(loginParam: LoginParam): User {
|
||||||
@@ -27,6 +27,15 @@ object UserConverter {
|
|||||||
lastLoginIp = user.lastLoginIp,
|
lastLoginIp = user.lastLoginIp,
|
||||||
createTime = user.createTime,
|
createTime = user.createTime,
|
||||||
updateTime = user.updateTime,
|
updateTime = user.updateTime,
|
||||||
|
userInfo = user.userInfo?.let { UserInfoVo(
|
||||||
|
id = it.id,
|
||||||
|
userId = it.userId,
|
||||||
|
nickName = it.nickName,
|
||||||
|
avatar = it.avatar,
|
||||||
|
email = it.email,
|
||||||
|
createTime = it.createTime,
|
||||||
|
updateTime = it.updateTime
|
||||||
|
) },
|
||||||
modules = user.modules?.map {
|
modules = user.modules?.map {
|
||||||
ModuleVo(
|
ModuleVo(
|
||||||
id = it.id,
|
id = it.id,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.converter
|
package top.fatweb.api.converter.system
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage
|
import com.baomidou.mybatisplus.core.metadata.IPage
|
||||||
import top.fatweb.api.entity.system.SysLog
|
import top.fatweb.api.entity.system.SysLog
|
||||||
@@ -104,6 +104,9 @@ class User() : Serializable {
|
|||||||
@Version
|
@Version
|
||||||
var version: Int? = null
|
var version: Int? = null
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
var userInfo: UserInfo? = null
|
||||||
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
var roles: List<Role>? = null
|
var roles: List<Role>? = null
|
||||||
|
|
||||||
@@ -123,6 +126,6 @@ class User() : Serializable {
|
|||||||
var operations: List<Operation>? = null
|
var operations: List<Operation>? = null
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "User(id=$id, username=$username, password=$password, locking=$locking, expiration=$expiration, credentialsExpiration=$credentialsExpiration, enable=$enable, currentLoginTime=$currentLoginTime, currentLoginIp=$currentLoginIp, lastLoginTime=$lastLoginTime, lastLoginIp=$lastLoginIp, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, roles=$roles, groups=$groups, menus=$menus, elements=$elements, operations=$operations)"
|
return "User(id=$id, username=$username, password=$password, locking=$locking, expiration=$expiration, credentialsExpiration=$credentialsExpiration, enable=$enable, currentLoginTime=$currentLoginTime, currentLoginIp=$currentLoginIp, lastLoginTime=$lastLoginTime, lastLoginIp=$lastLoginIp, createTime=$createTime, updateTime=$updateTime, deleted=$deleted, version=$version, userInfo=$userInfo, roles=$roles, groups=$groups, modules=$modules, menus=$menus, elements=$elements, operations=$operations)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import java.time.LocalDateTime
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 用户信息表
|
* 用户资料表
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author FatttSnake
|
* @author FatttSnake
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import org.springframework.security.core.context.SecurityContextHolder
|
|||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
import org.springframework.util.StringUtils
|
import org.springframework.util.StringUtils
|
||||||
import org.springframework.web.filter.OncePerRequestFilter
|
import org.springframework.web.filter.OncePerRequestFilter
|
||||||
import top.fatweb.api.constant.SecurityConstants
|
|
||||||
import top.fatweb.api.entity.permission.LoginUser
|
import top.fatweb.api.entity.permission.LoginUser
|
||||||
import top.fatweb.api.exception.TokenHasExpiredException
|
import top.fatweb.api.exception.TokenHasExpiredException
|
||||||
|
import top.fatweb.api.properties.SecurityProperties
|
||||||
import top.fatweb.api.util.JwtUtil
|
import top.fatweb.api.util.JwtUtil
|
||||||
import top.fatweb.api.util.RedisUtil
|
import top.fatweb.api.util.RedisUtil
|
||||||
import top.fatweb.api.util.WebUtil
|
import top.fatweb.api.util.WebUtil
|
||||||
@@ -20,7 +20,7 @@ class JwtAuthenticationTokenFilter(private val redisUtil: RedisUtil) : OncePerRe
|
|||||||
override fun doFilterInternal(
|
override fun doFilterInternal(
|
||||||
request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain
|
request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain
|
||||||
) {
|
) {
|
||||||
val tokenWithPrefix = request.getHeader(SecurityConstants.headerString)
|
val tokenWithPrefix = request.getHeader(SecurityProperties.headerString)
|
||||||
|
|
||||||
if (!StringUtils.hasText(tokenWithPrefix) || "/error/thrown" == request.servletPath) {
|
if (!StringUtils.hasText(tokenWithPrefix) || "/error/thrown" == request.servletPath) {
|
||||||
filterChain.doFilter(request, response)
|
filterChain.doFilter(request, response)
|
||||||
@@ -30,11 +30,11 @@ 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 = "${SecurityConstants.jwtIssuer}_login:" + token
|
val redisKey = "${SecurityProperties.jwtIssuer}_login:" + token
|
||||||
val loginUser = redisUtil.getObject<LoginUser>(redisKey)
|
val loginUser = redisUtil.getObject<LoginUser>(redisKey)
|
||||||
loginUser ?: let { throw TokenHasExpiredException() }
|
loginUser ?: let { throw TokenHasExpiredException() }
|
||||||
|
|
||||||
redisUtil.setExpire(redisKey, SecurityConstants.redisTtl, SecurityConstants.redisTtlUnit)
|
redisUtil.setExpire(redisKey, 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
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import top.fatweb.api.entity.permission.UserInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 用户信息表 Mapper 接口
|
* 用户资料表 Mapper 接口
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author FatttSnake
|
* @author FatttSnake
|
||||||
|
|||||||
13
src/main/kotlin/top/fatweb/api/properties/AdminProperties.kt
Normal file
13
src/main/kotlin/top/fatweb/api/properties/AdminProperties.kt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package top.fatweb.api.properties
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties("app.admin")
|
||||||
|
object AdminProperties {
|
||||||
|
var username = "admin"
|
||||||
|
var password: String? = null
|
||||||
|
var nickName = "Administrator"
|
||||||
|
var email = "admin@fatweb.top"
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.constant
|
package top.fatweb.api.properties
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
@@ -6,7 +6,7 @@ import java.util.concurrent.TimeUnit
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties("app.security")
|
@ConfigurationProperties("app.security")
|
||||||
object SecurityConstants {
|
object SecurityProperties {
|
||||||
var headerString = "Authorization"
|
var headerString = "Authorization"
|
||||||
|
|
||||||
var tokenPrefix = "Bearer "
|
var tokenPrefix = "Bearer "
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.constant
|
package top.fatweb.api.properties
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
@@ -8,7 +8,7 @@ import java.time.ZonedDateTime
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties("app")
|
@ConfigurationProperties("app")
|
||||||
object ServerConstants {
|
object ServerProperties {
|
||||||
lateinit var version: String
|
lateinit var version: String
|
||||||
|
|
||||||
lateinit var buildTime: String
|
lateinit var buildTime: String
|
||||||
@@ -2,8 +2,8 @@ package top.fatweb.api.service.permission
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import top.fatweb.api.entity.permission.User
|
import top.fatweb.api.entity.permission.User
|
||||||
import top.fatweb.api.vo.authentication.LoginVo
|
import top.fatweb.api.vo.permission.LoginVo
|
||||||
import top.fatweb.api.vo.authentication.TokenVo
|
import top.fatweb.api.vo.permission.TokenVo
|
||||||
|
|
||||||
interface IAuthenticationService {
|
interface IAuthenticationService {
|
||||||
fun login(request: HttpServletRequest, user: User): LoginVo
|
fun login(request: HttpServletRequest, user: User): LoginVo
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import top.fatweb.api.entity.permission.UserInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 用户信息表 服务类
|
* 用户资料表 服务类
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author FatttSnake
|
* @author FatttSnake
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ import org.slf4j.LoggerFactory
|
|||||||
import org.springframework.security.authentication.AuthenticationManager
|
import org.springframework.security.authentication.AuthenticationManager
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import top.fatweb.api.constant.SecurityConstants
|
|
||||||
import top.fatweb.api.entity.permission.LoginUser
|
import top.fatweb.api.entity.permission.LoginUser
|
||||||
import top.fatweb.api.entity.permission.User
|
import top.fatweb.api.entity.permission.User
|
||||||
import top.fatweb.api.exception.TokenHasExpiredException
|
import top.fatweb.api.exception.TokenHasExpiredException
|
||||||
|
import top.fatweb.api.properties.SecurityProperties
|
||||||
import top.fatweb.api.service.permission.IAuthenticationService
|
import top.fatweb.api.service.permission.IAuthenticationService
|
||||||
import top.fatweb.api.service.permission.IUserService
|
import top.fatweb.api.service.permission.IUserService
|
||||||
import top.fatweb.api.util.JwtUtil
|
import top.fatweb.api.util.JwtUtil
|
||||||
import top.fatweb.api.util.RedisUtil
|
import top.fatweb.api.util.RedisUtil
|
||||||
import top.fatweb.api.util.WebUtil
|
import top.fatweb.api.util.WebUtil
|
||||||
import top.fatweb.api.vo.authentication.LoginVo
|
import top.fatweb.api.vo.permission.LoginVo
|
||||||
import top.fatweb.api.vo.authentication.TokenVo
|
import top.fatweb.api.vo.permission.TokenVo
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
|
|
||||||
@@ -54,18 +54,18 @@ class AuthenticationServiceImpl(
|
|||||||
throw RuntimeException("Login failed")
|
throw RuntimeException("Login failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
val redisKey = "${SecurityConstants.jwtIssuer}_login:" + jwt
|
val redisKey = "${SecurityProperties.jwtIssuer}_login:" + jwt
|
||||||
redisUtil.setObject(redisKey, loginUser, SecurityConstants.redisTtl, SecurityConstants.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)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun logout(token: String): Boolean = redisUtil.delObject("${SecurityConstants.jwtIssuer}_login:" + token)
|
override fun logout(token: String): Boolean = redisUtil.delObject("${SecurityProperties.jwtIssuer}_login:" + token)
|
||||||
|
|
||||||
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 = "${SecurityConstants.jwtIssuer}_login:" + token
|
val oldRedisKey = "${SecurityProperties.jwtIssuer}_login:" + token
|
||||||
redisUtil.delObject(oldRedisKey)
|
redisUtil.delObject(oldRedisKey)
|
||||||
val jwt = JwtUtil.createJwt(WebUtil.getLoginUserId().toString())
|
val jwt = JwtUtil.createJwt(WebUtil.getLoginUserId().toString())
|
||||||
|
|
||||||
@@ -73,9 +73,9 @@ class AuthenticationServiceImpl(
|
|||||||
throw RuntimeException("Login failed")
|
throw RuntimeException("Login failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
val redisKey = "${SecurityConstants.jwtIssuer}_login:" + jwt
|
val redisKey = "${SecurityProperties.jwtIssuer}_login:" + jwt
|
||||||
redisUtil.setObject(
|
redisUtil.setObject(
|
||||||
redisKey, loginUser, SecurityConstants.redisTtl, SecurityConstants.redisTtlUnit
|
redisKey, loginUser, SecurityProperties.redisTtl, SecurityProperties.redisTtlUnit
|
||||||
)
|
)
|
||||||
|
|
||||||
return TokenVo(jwt)
|
return TokenVo(jwt)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import top.fatweb.api.service.permission.IUserInfoService
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 用户信息表 服务实现类
|
* 用户资料表 服务实现类
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author FatttSnake
|
* @author FatttSnake
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package top.fatweb.api.util
|
|||||||
import com.auth0.jwt.JWT
|
import com.auth0.jwt.JWT
|
||||||
import com.auth0.jwt.algorithms.Algorithm
|
import com.auth0.jwt.algorithms.Algorithm
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT
|
import com.auth0.jwt.interfaces.DecodedJWT
|
||||||
import top.fatweb.api.constant.SecurityConstants
|
import top.fatweb.api.properties.SecurityProperties
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
@@ -17,7 +17,7 @@ object JwtUtil {
|
|||||||
* @return 密钥
|
* @return 密钥
|
||||||
*/
|
*/
|
||||||
private fun generalKey(): SecretKeySpec {
|
private fun generalKey(): SecretKeySpec {
|
||||||
val encodeKey = Base64.getDecoder().decode(SecurityConstants.jwtKey)
|
val encodeKey = Base64.getDecoder().decode(SecurityProperties.jwtKey)
|
||||||
return SecretKeySpec(encodeKey, 0, encodeKey.size, "AES")
|
return SecretKeySpec(encodeKey, 0, encodeKey.size, "AES")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,8 +34,8 @@ object JwtUtil {
|
|||||||
*/
|
*/
|
||||||
fun createJwt(
|
fun createJwt(
|
||||||
subject: String,
|
subject: String,
|
||||||
ttl: Long = SecurityConstants.jwtTtl,
|
ttl: Long = SecurityProperties.jwtTtl,
|
||||||
timeUnit: TimeUnit = SecurityConstants.jwtTtlUnit,
|
timeUnit: TimeUnit = SecurityProperties.jwtTtlUnit,
|
||||||
uuid: String = getUUID()
|
uuid: String = getUUID()
|
||||||
): String? {
|
): String? {
|
||||||
val nowMillis = System.currentTimeMillis()
|
val nowMillis = System.currentTimeMillis()
|
||||||
@@ -52,7 +52,7 @@ object JwtUtil {
|
|||||||
val expMillis = nowMillis + unitTtl
|
val expMillis = nowMillis + unitTtl
|
||||||
val expDate = Date(expMillis)
|
val expDate = Date(expMillis)
|
||||||
|
|
||||||
return JWT.create().withJWTId(uuid).withSubject(subject).withIssuer(SecurityConstants.jwtIssuer)
|
return JWT.create().withJWTId(uuid).withSubject(subject).withIssuer(SecurityProperties.jwtIssuer)
|
||||||
.withIssuedAt(nowDate).withExpiresAt(expDate).sign(algorithm())
|
.withIssuedAt(nowDate).withExpiresAt(expDate).sign(algorithm())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package top.fatweb.api.util
|
|||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import org.springframework.security.core.context.SecurityContextHolder
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
import top.fatweb.api.constant.SecurityConstants
|
|
||||||
import top.fatweb.api.entity.permission.LoginUser
|
import top.fatweb.api.entity.permission.LoginUser
|
||||||
|
import top.fatweb.api.properties.SecurityProperties
|
||||||
|
|
||||||
object WebUtil {
|
object WebUtil {
|
||||||
fun getLoginUser() = if (SecurityContextHolder.getContext().authentication.principal is String) null
|
fun getLoginUser() = if (SecurityContextHolder.getContext().authentication.principal is String) null
|
||||||
@@ -13,7 +13,7 @@ object WebUtil {
|
|||||||
|
|
||||||
fun getLoginUsername() = getLoginUser()?.user?.username
|
fun getLoginUsername() = getLoginUser()?.user?.username
|
||||||
|
|
||||||
fun getToken(tokenWithPrefix: String) = tokenWithPrefix.removePrefix(SecurityConstants.tokenPrefix)
|
fun getToken(tokenWithPrefix: String) = tokenWithPrefix.removePrefix(SecurityProperties.tokenPrefix)
|
||||||
|
|
||||||
fun getToken(request: HttpServletRequest) = getToken(request.getHeader(SecurityConstants.headerString))
|
fun getToken(request: HttpServletRequest) = getToken(request.getHeader(SecurityProperties.headerString))
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.vo.authentication
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.vo.authentication
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.vo.authentication
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.vo.authentication
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.vo.authentication
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.vo.authentication
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
|
||||||
31
src/main/kotlin/top/fatweb/api/vo/permission/UserInfoVo.kt
Normal file
31
src/main/kotlin/top/fatweb/api/vo/permission/UserInfoVo.kt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
@Schema(description = "用户资料返回参数")
|
||||||
|
data class UserInfoVo(
|
||||||
|
@JsonSerialize(using = ToStringSerializer::class)
|
||||||
|
val id: Long?,
|
||||||
|
|
||||||
|
@Schema(description = "用户ID")
|
||||||
|
@JsonSerialize(using = ToStringSerializer::class)
|
||||||
|
val userId: Long?,
|
||||||
|
|
||||||
|
@Schema(description = "昵称", example = "User")
|
||||||
|
val nickName: String?,
|
||||||
|
|
||||||
|
@Schema(description = "头像")
|
||||||
|
val avatar: String?,
|
||||||
|
|
||||||
|
@Schema(description = "邮箱", example = "user@fatweb.top")
|
||||||
|
val email: String?,
|
||||||
|
|
||||||
|
@Schema(description = "创建时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
|
val createTime: LocalDateTime?,
|
||||||
|
|
||||||
|
@Schema(description = "修改时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
|
val updateTime: LocalDateTime?
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package top.fatweb.api.vo.authentication
|
package top.fatweb.api.vo.permission
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
|
||||||
@@ -43,6 +43,9 @@ data class UserWithInfoVo(
|
|||||||
@Schema(description = "修改时间", example = "1900-01-01T00:00:00.000Z")
|
@Schema(description = "修改时间", example = "1900-01-01T00:00:00.000Z")
|
||||||
val updateTime: LocalDateTime?,
|
val updateTime: LocalDateTime?,
|
||||||
|
|
||||||
|
@Schema(description = "用户资料")
|
||||||
|
val userInfo: UserInfoVo?,
|
||||||
|
|
||||||
@Schema(description = "模块列表")
|
@Schema(description = "模块列表")
|
||||||
val modules: List<ModuleVo>?,
|
val modules: List<ModuleVo>?,
|
||||||
|
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
app:
|
app:
|
||||||
|
admin:
|
||||||
|
# username: admin # Username of administrator
|
||||||
|
# password: admin # Default password of administrator
|
||||||
|
# nick-name: Administrator # Nickname of administrator
|
||||||
|
# email: admin@fatweb.top # Email of administrator
|
||||||
security:
|
security:
|
||||||
# header-string: "Authorization" # The key of head to get token
|
# header-string: "Authorization" # The key of head to get token
|
||||||
# token-prefix: "Bearer " # Token prefix
|
# token-prefix: "Bearer " # Token prefix
|
||||||
|
|||||||
@@ -10,5 +10,6 @@ create table if not exists t_user_info
|
|||||||
create_time datetime not null default (utc_timestamp()) comment '创建时间',
|
create_time datetime not null default (utc_timestamp()) comment '创建时间',
|
||||||
update_time datetime not null default (utc_timestamp()) comment '修改时间',
|
update_time datetime not null default (utc_timestamp()) comment '修改时间',
|
||||||
deleted bigint not null default 0,
|
deleted bigint not null default 0,
|
||||||
version int not null default 0
|
version int not null default 0,
|
||||||
) comment '用户信息表';
|
constraint t_user_info_unique unique (user_id, deleted)
|
||||||
|
) comment '用户资料表';
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
t_user.deleted as user_deleted,
|
t_user.deleted as user_deleted,
|
||||||
t_user.version as user_version,
|
t_user.version as user_version,
|
||||||
tui.id as user_info_id,
|
tui.id as user_info_id,
|
||||||
|
tui.user_id as user_info_user_id,
|
||||||
tui.nick_name as user_info_nick_name,
|
tui.nick_name as user_info_nick_name,
|
||||||
tui.avatar as user_info_avatar,
|
tui.avatar as user_info_avatar,
|
||||||
tui.email as user_info_email,
|
tui.email as user_info_email,
|
||||||
@@ -61,7 +62,7 @@
|
|||||||
and t_user.username = #{username};
|
and t_user.username = #{username};
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<resultMap id="userBase" type="user">
|
<resultMap id="userBaseMap" type="user">
|
||||||
<id property="id" column="user_id"/>
|
<id property="id" column="user_id"/>
|
||||||
<result property="username" column="user_username"/>
|
<result property="username" column="user_username"/>
|
||||||
<result property="locking" column="user_locking"/>
|
<result property="locking" column="user_locking"/>
|
||||||
@@ -78,8 +79,21 @@
|
|||||||
<result property="version" column="user_version"/>
|
<result property="version" column="user_version"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<resultMap id="userWithPowerMap" type="user" extends="userBase">
|
<resultMap id="userInfoMap" type="userInfo">
|
||||||
|
<id property="id" column="user_info_id"/>
|
||||||
|
<result property="userId" column="user_info_user_id"/>
|
||||||
|
<result property="nickName" column="user_info_nick_name"/>
|
||||||
|
<result property="avatar" column="user_info_avatar"/>
|
||||||
|
<result property="email" column="user_info_email"/>
|
||||||
|
<result property="createTime" column="user_info_create_time"/>
|
||||||
|
<result property="updateTime" column="user_info_update_time"/>
|
||||||
|
<result property="deleted" column="user_info_deleted"/>
|
||||||
|
<result property="version" column="user_info_version"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<resultMap id="userWithPowerMap" type="user" extends="userBaseMap">
|
||||||
<result property="password" column="user_password"/>
|
<result property="password" column="user_password"/>
|
||||||
|
<association property="userInfo" resultMap="userInfoMap"/>
|
||||||
<collection property="modules" ofType="module">
|
<collection property="modules" ofType="module">
|
||||||
<id property="id" column="module_id"/>
|
<id property="id" column="module_id"/>
|
||||||
<result property="name" column="module_name"/>
|
<result property="name" column="module_name"/>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.junit.jupiter.api.extension.ExtendWith
|
|||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.test.context.junit.jupiter.SpringExtension
|
import org.springframework.test.context.junit.jupiter.SpringExtension
|
||||||
import top.fatweb.api.constant.SecurityConstants
|
import top.fatweb.api.properties.SecurityProperties
|
||||||
import top.fatweb.api.util.ByteUtil
|
import top.fatweb.api.util.ByteUtil
|
||||||
import top.fatweb.api.util.JwtUtil
|
import top.fatweb.api.util.JwtUtil
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ class FatWebApiApplicationTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun removePrefixTest() {
|
fun removePrefixTest() {
|
||||||
assertEquals("12312", "Bearer 12312".removePrefix(SecurityConstants.tokenPrefix))
|
assertEquals("12312", "Bearer 12312".removePrefix(SecurityProperties.tokenPrefix))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user