添加登录组件
This commit is contained in:
parent
86006196c8
commit
b6db17290b
5
pom.xml
5
pom.xml
|
@ -26,6 +26,11 @@
|
|||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mindrot</groupId>
|
||||
<artifactId>jbcrypt</artifactId>
|
||||
<version>0.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
|
|
|
@ -9,7 +9,7 @@ import jakarta.servlet.http.HttpServletResponse
|
|||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.CookieValue
|
||||
import org.springframework.web.bind.annotation.CrossOrigin
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
@ -23,7 +23,7 @@ class TokenController(
|
|||
/**
|
||||
* 创建 Token 组件
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
@GetMapping("/create")
|
||||
fun createToken(
|
||||
@CookieValue("session") token: String?, httpServletResponse: HttpServletResponse,
|
||||
@RequestParam("return") returnLink: String?,
|
||||
|
|
|
@ -4,15 +4,19 @@ import com.frontleaves.general.utils.BaseResponse
|
|||
import com.frontleaves.general.utils.ErrorCode
|
||||
import com.frontleaves.general.utils.ResultUtil
|
||||
import com.xlf.dromstarkotlin.entity.voData.SignInVO
|
||||
import com.xlf.dromstarkotlin.entity.voData.SignUpVO
|
||||
import com.xlf.dromstarkotlin.exception.BusinessException
|
||||
import com.xlf.dromstarkotlin.services.TokenService
|
||||
import com.xlf.dromstarkotlin.services.UserService
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.CookieValue
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import java.util.Date
|
||||
|
||||
/**
|
||||
* 用户控制器
|
||||
|
@ -25,31 +29,72 @@ import org.springframework.web.bind.annotation.RestController
|
|||
@RestController
|
||||
@RequestMapping("/api/user")
|
||||
class UserController(
|
||||
private val tokenService: TokenService
|
||||
private val tokenService: TokenService,
|
||||
private val userService: UserService
|
||||
) {
|
||||
/**
|
||||
* 用户登录组件
|
||||
*/
|
||||
@PostMapping("/sign/in")
|
||||
@GetMapping("/sign/in")
|
||||
fun signIn(
|
||||
signInVO: SignInVO?, @CookieValue("sessionId") token: String?, httpServletResponse: HttpServletResponse,
|
||||
@RequestBody signInVO: SignInVO?, @CookieValue("session") token: String?, httpServletResponse: HttpServletResponse,
|
||||
httpServletRequest: HttpServletRequest
|
||||
): ResponseEntity<BaseResponse>? {
|
||||
): ResponseEntity<BaseResponse> {
|
||||
// 判断请求体是否为空
|
||||
if (signInVO == null) {
|
||||
return BusinessException().backInfo(ErrorCode.MISSING_REQUEST_BODY, httpServletRequest)
|
||||
} else {
|
||||
// 判断时间戳
|
||||
if (signInVO.timestamp + 5000 < Date().time || signInVO.timestamp - 5000 > Date().time) {
|
||||
return ResultUtil.error(ErrorCode.TIMESTAMP_EXPIRED, httpServletRequest)
|
||||
}
|
||||
// 对 Token 进行校验
|
||||
if (token != null) {
|
||||
return if (token != null) {
|
||||
// 对 token 进行校验
|
||||
if (!tokenService.tokenVerify(token, httpServletResponse)) {
|
||||
// 校验失败
|
||||
return BusinessException().backInfo(ErrorCode.TOKEN_VERIFY_FAILED, httpServletRequest)
|
||||
BusinessException().backInfo(ErrorCode.TOKEN_VERIFY_FAILED, httpServletRequest)
|
||||
} else {
|
||||
// 用户登录操作
|
||||
userService.signIn(signInVO, token, httpServletRequest)
|
||||
}
|
||||
} else {
|
||||
// 跳转至创建 Token 页面
|
||||
return ResultUtil.redirect("/api/token/create", httpServletRequest)
|
||||
ResultUtil.redirect("/api/token/create", httpServletRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注册组件
|
||||
*/
|
||||
@GetMapping("/sign/up")
|
||||
fun signUp(
|
||||
@RequestBody signUpVO: SignUpVO?, @CookieValue("session") token: String?, httpServletResponse: HttpServletResponse,
|
||||
httpServletRequest: HttpServletRequest
|
||||
): ResponseEntity<BaseResponse> {
|
||||
// 判断请求体是否为空
|
||||
if (signUpVO == null) {
|
||||
return ResultUtil.error(ErrorCode.MISSING_REQUEST_BODY, httpServletRequest)
|
||||
} else {
|
||||
// 判断时间戳
|
||||
if (signUpVO.timestamp + 5000 < Date().time || signUpVO.timestamp - 5000 > Date().time) {
|
||||
return ResultUtil.error(ErrorCode.TIMESTAMP_EXPIRED, httpServletRequest)
|
||||
}
|
||||
// 对 Token 进行校验
|
||||
return if (token != null) {
|
||||
// 对 token 进行校验
|
||||
if (!tokenService.tokenVerify(token, httpServletResponse)) {
|
||||
// 校验失败
|
||||
BusinessException().backInfo(ErrorCode.TOKEN_VERIFY_FAILED, httpServletRequest)
|
||||
} else {
|
||||
// 用户登录操作
|
||||
userService.signUp(signUpVO, token, httpServletRequest)
|
||||
}
|
||||
} else {
|
||||
// 跳转至创建 Token 页面
|
||||
ResultUtil.redirect("/api/token/create", httpServletRequest)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
|
@ -6,6 +6,8 @@ data class UserDO(
|
|||
var id: Long?,
|
||||
var user: String?,
|
||||
var password: String?,
|
||||
var email: String?,
|
||||
var tel: String?,
|
||||
var permission: Short?,
|
||||
var createdAt: Timestamp?,
|
||||
var updatedAt: Timestamp?
|
||||
|
|
|
@ -7,8 +7,8 @@ package com.xlf.dromstarkotlin.entity.voData
|
|||
* @since v1.0.0
|
||||
*/
|
||||
data class SignInVO (
|
||||
var action: String? = null,
|
||||
var username: String? = null,
|
||||
var password: String? = null,
|
||||
var timestamp: Long? = null,
|
||||
val action: String,
|
||||
val username: String,
|
||||
val password: String,
|
||||
val timestamp: Long,
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
package com.xlf.dromstarkotlin.entity.voData
|
||||
|
||||
/**
|
||||
* 注册用户信息自定义实体类
|
||||
*
|
||||
* @author 筱锋xiao_lfeng
|
||||
* @since v1.0.0
|
||||
*/
|
||||
data class SignUpVO (
|
||||
val action: String,
|
||||
val username: String,
|
||||
val password: String,
|
||||
val email: String,
|
||||
val telephone: String?,
|
||||
val timestamp: Long,
|
||||
)
|
|
@ -5,6 +5,7 @@ import org.apache.ibatis.annotations.Delete
|
|||
import org.apache.ibatis.annotations.Insert
|
||||
import org.apache.ibatis.annotations.Mapper
|
||||
import org.apache.ibatis.annotations.Select
|
||||
import org.apache.ibatis.annotations.Update
|
||||
|
||||
@Mapper
|
||||
interface TokenMapper {
|
||||
|
@ -19,4 +20,7 @@ interface TokenMapper {
|
|||
|
||||
@Insert("INSERT INTO dormstar.ds_token (user_id, token, user_agent, ip, created_at) VALUES (#{userId}, #{token}, #{userAgent}, #{ip}, #{createdAt})")
|
||||
fun insertToken(token: TokenDO): Boolean
|
||||
|
||||
@Update("UPDATE dormstar.ds_token SET user_id = #{userId}, updated_at = #{updatedAt} WHERE token = #{token}")
|
||||
fun tokenAuthorization(token: TokenDO): Boolean
|
||||
}
|
|
@ -1,4 +1,19 @@
|
|||
package com.xlf.dromstarkotlin.mapper
|
||||
|
||||
import com.xlf.dromstarkotlin.entity.doData.UserDO
|
||||
import org.apache.ibatis.annotations.Insert
|
||||
import org.apache.ibatis.annotations.Mapper
|
||||
import org.apache.ibatis.annotations.Select
|
||||
|
||||
@Mapper
|
||||
interface UserMapper {
|
||||
|
||||
@Select("SELECT * FROM dormstar.ds_user WHERE user = #{username}")
|
||||
fun getUserByUsername(username: String?): UserDO?
|
||||
|
||||
@Select("SELECT * FROM dormstar.ds_user WHERE user = #{username} OR email = #{email} OR tel = #{phone} LIMIT 1")
|
||||
fun getUser(username: String, email: String, phone: String?): UserDO?
|
||||
|
||||
@Insert("INSERT INTO dormstar.ds_user (user, password, email, tel, created_at) VALUES (#{user}, #{password}, #{email}, #{tel}, #{createdAt})")
|
||||
fun insertUser(user: UserDO): Boolean
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package com.xlf.dromstarkotlin.services
|
||||
|
||||
import com.frontleaves.general.utils.BaseResponse
|
||||
import com.frontleaves.general.utils.ErrorCode
|
||||
import com.frontleaves.general.utils.ResultUtil
|
||||
import com.xlf.dromstarkotlin.entity.doData.UserDO
|
||||
import com.xlf.dromstarkotlin.entity.voData.SignInVO
|
||||
import com.xlf.dromstarkotlin.entity.voData.SignUpVO
|
||||
import com.xlf.dromstarkotlin.mapper.TokenMapper
|
||||
import com.xlf.dromstarkotlin.mapper.UserMapper
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import org.mindrot.jbcrypt.BCrypt
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.sql.Timestamp
|
||||
import java.util.*
|
||||
|
||||
@Service
|
||||
class UserService(
|
||||
val userMapper: UserMapper,
|
||||
val tokenMapper: TokenMapper
|
||||
) {
|
||||
|
||||
@Transactional
|
||||
fun signIn(
|
||||
signInVO: SignInVO, token:String, httpServletRequest: HttpServletRequest
|
||||
): ResponseEntity<BaseResponse> {
|
||||
// 检查用户是否存在
|
||||
val user = userMapper.getUserByUsername(signInVO.username)
|
||||
return if (user != null) {
|
||||
// 检查用户密码是否匹配
|
||||
if (BCrypt.checkpw(signInVO.password, user.password)) {
|
||||
val tokenDO = tokenMapper.getToken(token)
|
||||
.also { it!!.userId = user.id }
|
||||
if (tokenDO!!.userId == null) {
|
||||
// 授权 token
|
||||
if (tokenMapper.tokenAuthorization(tokenDO)) {
|
||||
ResultUtil.success("登陆成功", httpServletRequest)
|
||||
} else {
|
||||
ResultUtil.error(ErrorCode.DATABASE_UPDATE_OPERATION_FAILED, httpServletRequest)
|
||||
}
|
||||
} else {
|
||||
ResultUtil.error(ErrorCode.YOU_ARE_ALREADY_LOGIN, httpServletRequest)
|
||||
}
|
||||
} else {
|
||||
ResultUtil.error(ErrorCode.WRONG_PASSWORD, httpServletRequest)
|
||||
}
|
||||
} else {
|
||||
ResultUtil.error(ErrorCode.USER_NOT_FOUNDED, httpServletRequest)
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun signUp(
|
||||
signUpVO: SignUpVO, token: String, httpServletRequest: HttpServletRequest
|
||||
): ResponseEntity<BaseResponse> {
|
||||
// 检查用户和邮箱是否存在
|
||||
val user = userMapper.getUser(signUpVO.username, signUpVO.email, signUpVO.telephone)
|
||||
if (user == null) {
|
||||
val tokenDO = tokenMapper.getToken(token)
|
||||
if (tokenDO!!.userId == null) {
|
||||
// 处理用户注册程序
|
||||
val hashPassword = BCrypt.hashpw(signUpVO.password, BCrypt.gensalt())
|
||||
val newUser = UserDO(null, signUpVO.username, hashPassword, signUpVO.email, signUpVO.telephone, 0, Timestamp(Date().time), null)
|
||||
// 数据输入数据库
|
||||
return if (userMapper.insertUser(newUser)) {
|
||||
// 授权 token
|
||||
if (tokenMapper.tokenAuthorization(tokenDO)) {
|
||||
ResultUtil.success("注册成功", httpServletRequest)
|
||||
} else {
|
||||
ResultUtil.error(ErrorCode.DATABASE_UPDATE_OPERATION_FAILED, httpServletRequest)
|
||||
}
|
||||
} else {
|
||||
ResultUtil.error(ErrorCode.DATABASE_INSERT_OPERATION_FAILED, httpServletRequest)
|
||||
}
|
||||
} else {
|
||||
return ResultUtil.error(ErrorCode.YOU_ARE_ALREADY_LOGIN, httpServletRequest)
|
||||
}
|
||||
} else {
|
||||
return ResultUtil.error(ErrorCode.USER_EXIST, httpServletRequest)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -66,6 +66,12 @@ enum class ErrorCode(val output: String, val code: Int, val message: String, val
|
|||
"无法生成验证密钥(VerifyKey)",
|
||||
HttpStatus.BAD_REQUEST
|
||||
),
|
||||
YOU_ARE_ALREADY_LOGIN(
|
||||
"YouAreAlreadyLogin",
|
||||
40026,
|
||||
"您已经登录",
|
||||
HttpStatus.BAD_REQUEST
|
||||
),
|
||||
YOU_ARE_NOT_LOGIN(
|
||||
"YouAreNotLogin",
|
||||
40110,
|
||||
|
@ -120,6 +126,12 @@ enum class ErrorCode(val output: String, val code: Int, val message: String, val
|
|||
"apikey不正确",
|
||||
HttpStatus.FORBIDDEN
|
||||
),
|
||||
TIMESTAMP_EXPIRED(
|
||||
"TimestampExpired",
|
||||
40318,
|
||||
"时间戳过期",
|
||||
HttpStatus.FORBIDDEN
|
||||
),
|
||||
METHOD_NOT_ALLOWED(
|
||||
"MethodNotAllowed",
|
||||
40510,
|
||||
|
|
|
@ -15,7 +15,8 @@ class ResultUtil constructor(val output: String, val code: Int, val message: Str
|
|||
*
|
||||
* @return BaseResponse
|
||||
*/
|
||||
fun success(): ResponseEntity<BaseResponse> {
|
||||
fun success(httpServletRequest: HttpServletRequest): ResponseEntity<BaseResponse> {
|
||||
println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>Success | Message:OK | URI:${httpServletRequest.requestURI}")
|
||||
return ResponseEntity
|
||||
.status(200)
|
||||
.body(BaseResponse())
|
||||
|
|
Loading…
Reference in New Issue
Block a user