添加登录组件
This commit is contained in:
parent
86006196c8
commit
b6db17290b
5
pom.xml
5
pom.xml
@ -26,6 +26,11 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-aop</artifactId>
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mindrot</groupId>
|
||||||
|
<artifactId>jbcrypt</artifactId>
|
||||||
|
<version>0.4</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.module</groupId>
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
<artifactId>jackson-module-kotlin</artifactId>
|
<artifactId>jackson-module-kotlin</artifactId>
|
||||||
|
@ -9,7 +9,7 @@ import jakarta.servlet.http.HttpServletResponse
|
|||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.web.bind.annotation.CookieValue
|
import org.springframework.web.bind.annotation.CookieValue
|
||||||
import org.springframework.web.bind.annotation.CrossOrigin
|
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.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RequestParam
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
@ -23,7 +23,7 @@ class TokenController(
|
|||||||
/**
|
/**
|
||||||
* 创建 Token 组件
|
* 创建 Token 组件
|
||||||
*/
|
*/
|
||||||
@PostMapping("/create")
|
@GetMapping("/create")
|
||||||
fun createToken(
|
fun createToken(
|
||||||
@CookieValue("session") token: String?, httpServletResponse: HttpServletResponse,
|
@CookieValue("session") token: String?, httpServletResponse: HttpServletResponse,
|
||||||
@RequestParam("return") returnLink: String?,
|
@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.ErrorCode
|
||||||
import com.frontleaves.general.utils.ResultUtil
|
import com.frontleaves.general.utils.ResultUtil
|
||||||
import com.xlf.dromstarkotlin.entity.voData.SignInVO
|
import com.xlf.dromstarkotlin.entity.voData.SignInVO
|
||||||
|
import com.xlf.dromstarkotlin.entity.voData.SignUpVO
|
||||||
import com.xlf.dromstarkotlin.exception.BusinessException
|
import com.xlf.dromstarkotlin.exception.BusinessException
|
||||||
import com.xlf.dromstarkotlin.services.TokenService
|
import com.xlf.dromstarkotlin.services.TokenService
|
||||||
|
import com.xlf.dromstarkotlin.services.UserService
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import jakarta.servlet.http.HttpServletResponse
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.web.bind.annotation.CookieValue
|
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.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RestController
|
import org.springframework.web.bind.annotation.RestController
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户控制器
|
* 用户控制器
|
||||||
@ -25,31 +29,72 @@ import org.springframework.web.bind.annotation.RestController
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/user")
|
@RequestMapping("/api/user")
|
||||||
class UserController(
|
class UserController(
|
||||||
private val tokenService: TokenService
|
private val tokenService: TokenService,
|
||||||
|
private val userService: UserService
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* 用户登录组件
|
* 用户登录组件
|
||||||
*/
|
*/
|
||||||
@PostMapping("/sign/in")
|
@GetMapping("/sign/in")
|
||||||
fun signIn(
|
fun signIn(
|
||||||
signInVO: SignInVO?, @CookieValue("sessionId") token: String?, httpServletResponse: HttpServletResponse,
|
@RequestBody signInVO: SignInVO?, @CookieValue("session") token: String?, httpServletResponse: HttpServletResponse,
|
||||||
httpServletRequest: HttpServletRequest
|
httpServletRequest: HttpServletRequest
|
||||||
): ResponseEntity<BaseResponse>? {
|
): ResponseEntity<BaseResponse> {
|
||||||
|
// 判断请求体是否为空
|
||||||
if (signInVO == null) {
|
if (signInVO == null) {
|
||||||
return BusinessException().backInfo(ErrorCode.MISSING_REQUEST_BODY, httpServletRequest)
|
return BusinessException().backInfo(ErrorCode.MISSING_REQUEST_BODY, httpServletRequest)
|
||||||
} else {
|
} else {
|
||||||
|
// 判断时间戳
|
||||||
|
if (signInVO.timestamp + 5000 < Date().time || signInVO.timestamp - 5000 > Date().time) {
|
||||||
|
return ResultUtil.error(ErrorCode.TIMESTAMP_EXPIRED, httpServletRequest)
|
||||||
|
}
|
||||||
// 对 Token 进行校验
|
// 对 Token 进行校验
|
||||||
if (token != null) {
|
return if (token != null) {
|
||||||
// 对 token 进行校验
|
// 对 token 进行校验
|
||||||
if (!tokenService.tokenVerify(token, httpServletResponse)) {
|
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 {
|
} else {
|
||||||
// 跳转至创建 Token 页面
|
// 跳转至创建 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 id: Long?,
|
||||||
var user: String?,
|
var user: String?,
|
||||||
var password: String?,
|
var password: String?,
|
||||||
|
var email: String?,
|
||||||
|
var tel: String?,
|
||||||
var permission: Short?,
|
var permission: Short?,
|
||||||
var createdAt: Timestamp?,
|
var createdAt: Timestamp?,
|
||||||
var updatedAt: Timestamp?
|
var updatedAt: Timestamp?
|
||||||
|
@ -7,8 +7,8 @@ package com.xlf.dromstarkotlin.entity.voData
|
|||||||
* @since v1.0.0
|
* @since v1.0.0
|
||||||
*/
|
*/
|
||||||
data class SignInVO (
|
data class SignInVO (
|
||||||
var action: String? = null,
|
val action: String,
|
||||||
var username: String? = null,
|
val username: String,
|
||||||
var password: String? = null,
|
val password: String,
|
||||||
var timestamp: Long? = null,
|
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.Insert
|
||||||
import org.apache.ibatis.annotations.Mapper
|
import org.apache.ibatis.annotations.Mapper
|
||||||
import org.apache.ibatis.annotations.Select
|
import org.apache.ibatis.annotations.Select
|
||||||
|
import org.apache.ibatis.annotations.Update
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
interface TokenMapper {
|
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})")
|
@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
|
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
|
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 {
|
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)",
|
"无法生成验证密钥(VerifyKey)",
|
||||||
HttpStatus.BAD_REQUEST
|
HttpStatus.BAD_REQUEST
|
||||||
),
|
),
|
||||||
|
YOU_ARE_ALREADY_LOGIN(
|
||||||
|
"YouAreAlreadyLogin",
|
||||||
|
40026,
|
||||||
|
"您已经登录",
|
||||||
|
HttpStatus.BAD_REQUEST
|
||||||
|
),
|
||||||
YOU_ARE_NOT_LOGIN(
|
YOU_ARE_NOT_LOGIN(
|
||||||
"YouAreNotLogin",
|
"YouAreNotLogin",
|
||||||
40110,
|
40110,
|
||||||
@ -120,6 +126,12 @@ enum class ErrorCode(val output: String, val code: Int, val message: String, val
|
|||||||
"apikey不正确",
|
"apikey不正确",
|
||||||
HttpStatus.FORBIDDEN
|
HttpStatus.FORBIDDEN
|
||||||
),
|
),
|
||||||
|
TIMESTAMP_EXPIRED(
|
||||||
|
"TimestampExpired",
|
||||||
|
40318,
|
||||||
|
"时间戳过期",
|
||||||
|
HttpStatus.FORBIDDEN
|
||||||
|
),
|
||||||
METHOD_NOT_ALLOWED(
|
METHOD_NOT_ALLOWED(
|
||||||
"MethodNotAllowed",
|
"MethodNotAllowed",
|
||||||
40510,
|
40510,
|
||||||
|
@ -15,7 +15,8 @@ class ResultUtil constructor(val output: String, val code: Int, val message: Str
|
|||||||
*
|
*
|
||||||
* @return BaseResponse
|
* @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
|
return ResponseEntity
|
||||||
.status(200)
|
.status(200)
|
||||||
.body(BaseResponse())
|
.body(BaseResponse())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user