feat(auth): implement login logic with database and password verification
- Replace stub with MyBatis-Plus user query and password matching - Integrate kotlin-logging for structured logging across services - Add custom Log utility replacing direct SLF4J usage - Add kotlin-logging dependency to build configuration
This commit is contained in:
@@ -29,6 +29,7 @@ dependencies {
|
||||
implementation("com.baomidou:mybatis-plus-spring-boot4-starter:3.5.15")
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||
implementation("io.github.oshai:kotlin-logging-jvm:7.0.0")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package com.msksbr.bookmgr.controller
|
||||
|
||||
import com.msksbr.bookmgr.dto.UserLoginDTO
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.AuthService
|
||||
import jakarta.servlet.http.HttpSession
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import com.msksbr.bookmgr.template.Result
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
|
||||
/*
|
||||
* 登录接口
|
||||
@@ -21,23 +24,35 @@ class AuthController(
|
||||
@PostMapping("/login")
|
||||
fun login(
|
||||
@Valid
|
||||
@RequestBody
|
||||
loginDTO: UserLoginDTO,
|
||||
session: HttpSession
|
||||
session: HttpSession,
|
||||
request: HttpServletRequest
|
||||
) : Result<String> {
|
||||
log.info("Login from ${request.remoteAddr} username: ${loginDTO.username}")
|
||||
log.info("UA: ${request.getHeader("User-Agent")}")
|
||||
// 调用service验证
|
||||
val success=authService.login(loginDTO)
|
||||
return if (success) {
|
||||
val pass=authService.login(loginDTO)
|
||||
return if (pass) {
|
||||
// 登录成功,存入session
|
||||
session.setAttribute("loginUser", loginDTO.username)
|
||||
log.info("Login success")
|
||||
Result.success("login success")
|
||||
}else{
|
||||
log.info("Login failed")
|
||||
Result.error("username or password not match")
|
||||
}
|
||||
}
|
||||
@PostMapping("/logout")
|
||||
fun logout(session: HttpSession): Result<String> {
|
||||
fun logout(
|
||||
session: HttpSession,
|
||||
request:HttpServletRequest
|
||||
): Result<String> {
|
||||
log.info("Logout from ${request.remoteAddr}")
|
||||
log.info("UA: ${request.getHeader("User-Agent")}")
|
||||
// 直接销毁session
|
||||
session.invalidate()
|
||||
log.info("Logout success")
|
||||
return Result.success("logout successfully")
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import jakarta.validation.constraints.NotBlank
|
||||
|
||||
data class UserLoginDTO(
|
||||
@NotBlank(message = "username is required")
|
||||
var username: String,
|
||||
val username: String?,
|
||||
@NotBlank(message = "password is required")
|
||||
var password: String
|
||||
val password: String?
|
||||
)
|
||||
@@ -3,7 +3,7 @@ package com.msksbr.bookmgr.runner
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
|
||||
import com.msksbr.bookmgr.entity.User
|
||||
import com.msksbr.bookmgr.mapper.UserMapper
|
||||
import org.slf4j.LoggerFactory
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import org.springframework.boot.ApplicationArguments
|
||||
import org.springframework.boot.ApplicationRunner
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
@@ -15,45 +15,43 @@ class InitUserRunner(
|
||||
val passwordEncoder: PasswordEncoder,
|
||||
val userMapper: UserMapper,
|
||||
) : ApplicationRunner {
|
||||
private val logger = LoggerFactory.getLogger(InitUserRunner::class.java)
|
||||
|
||||
// 添加注解,失败时可回滚
|
||||
@Transactional
|
||||
override fun run(args: ApplicationArguments) {
|
||||
logger.info("Starting default user initialization")
|
||||
logger.debug("Querying for admin user")
|
||||
log.info("Starting default user initialization")
|
||||
log.debug("Querying for admin user")
|
||||
val existsAdmin = userMapper.selectOne(
|
||||
QueryWrapper<User>()
|
||||
.eq("username", "admin")
|
||||
)
|
||||
if (existsAdmin == null) {
|
||||
logger.info("Admin user not found, creating...")
|
||||
log.info("Admin user not found, creating...")
|
||||
insertAdmin()
|
||||
} else {
|
||||
logger.debug("Admin user already exists, skipping")
|
||||
log.debug("Admin user already exists, skipping")
|
||||
}
|
||||
logger.debug("Querying for common user01")
|
||||
log.debug("Querying for common user01")
|
||||
val existsUser01 = userMapper.selectOne(
|
||||
QueryWrapper<User>()
|
||||
.eq("username", "user01")
|
||||
)
|
||||
if (existsUser01 == null) {
|
||||
logger.info("Common user01 not found, creating...")
|
||||
log.info("Common user01 not found, creating...")
|
||||
insertUser01()
|
||||
} else {
|
||||
logger.debug("Common user01 already exists, skipping")
|
||||
log.debug("Common user01 already exists, skipping")
|
||||
}
|
||||
val existsUser02=userMapper.selectOne(
|
||||
QueryWrapper<User>()
|
||||
.eq("username", "user02")
|
||||
)
|
||||
if (existsUser02 == null) {
|
||||
logger.info("Common user02 not found, creating...")
|
||||
log.info("Common user02 not found, creating...")
|
||||
insertUser02()
|
||||
}else{
|
||||
logger.info("Common user02 already exists, skipping")
|
||||
log.info("Common user02 already exists, skipping")
|
||||
}
|
||||
logger.info("Default user initialization completed")
|
||||
log.info("Default user initialization completed")
|
||||
}
|
||||
|
||||
fun insertAdmin() {
|
||||
@@ -63,9 +61,9 @@ class InitUserRunner(
|
||||
password = passwordEncoder.encode("admin")!!,
|
||||
role = "admin"
|
||||
)
|
||||
logger.debug("Creating admin user: username={}, role={}", user.username, user.role)
|
||||
log.debug("Creating admin user: username=${user.username}, role=${user.role}")
|
||||
userMapper.insert(user)
|
||||
logger.info("Admin user created successfully")
|
||||
log.info("Admin user created successfully")
|
||||
}
|
||||
|
||||
fun insertUser01() {
|
||||
@@ -75,9 +73,9 @@ class InitUserRunner(
|
||||
password = passwordEncoder.encode("user01")!!,
|
||||
role = "user"
|
||||
)
|
||||
logger.debug("Creating common user: username={}, role={}", user.username, user.role)
|
||||
log.debug("Creating common user: username=${user.username}, role=${user.role}")
|
||||
userMapper.insert(user)
|
||||
logger.info("Common user created successfully")
|
||||
log.info("Common user created successfully")
|
||||
}
|
||||
fun insertUser02() {
|
||||
val user = User(
|
||||
@@ -86,8 +84,8 @@ class InitUserRunner(
|
||||
password = passwordEncoder.encode("user02")!!,
|
||||
role = "user"
|
||||
)
|
||||
logger.debug("Creating common user: username={}, role={}", user.username, user.role)
|
||||
log.debug("Creating common user: username=${user.username}, role=${user.role}")
|
||||
userMapper.insert(user)
|
||||
logger.info("Common user created successfully")
|
||||
log.info("Common user created successfully")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.msksbr.bookmgr.script
|
||||
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
val <T: Any> T.log: Logger
|
||||
get() = LoggerFactory.getLogger(this::class.java)
|
||||
@@ -1,12 +1,29 @@
|
||||
package com.msksbr.bookmgr.service.impl
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
|
||||
import com.msksbr.bookmgr.dto.UserLoginDTO
|
||||
import com.msksbr.bookmgr.entity.User
|
||||
import com.msksbr.bookmgr.mapper.UserMapper
|
||||
import com.msksbr.bookmgr.script.log
|
||||
import com.msksbr.bookmgr.service.AuthService
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class AuthServiceImpl: AuthService {
|
||||
class AuthServiceImpl(private val userMapper: UserMapper, private val passwordEncoder: PasswordEncoder) : AuthService {
|
||||
override fun login(loginDTO: UserLoginDTO): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
// 数据查询
|
||||
log.debug("Select user{username=${loginDTO.username}} from database")
|
||||
val user = userMapper.selectOne(
|
||||
QueryWrapper<User>()
|
||||
.eq("username", loginDTO.username)
|
||||
)
|
||||
// 找不到用户时直接返回false
|
||||
if (user == null) {
|
||||
log.debug("User ${loginDTO.username} does not exist")
|
||||
return false
|
||||
}
|
||||
// 比对密码
|
||||
return passwordEncoder.matches(loginDTO.password, user.password)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user