feat(新增): 用户登录完成
This commit is contained in:
parent
8fae01c4a2
commit
3783a74b56
|
@ -20,14 +20,15 @@ class AdminGenerator {
|
|||
private const val AUTHOR: String = "Bunny"
|
||||
|
||||
// 公共路径
|
||||
private const val OUTPUT_DIR: String = "D:\\MyFolder\\auth-admin\\auth-server\\services"
|
||||
// private const val OUTPUT_DIR: String = "D:\\MyFolder\\auth-admin\\auth-server\\services"
|
||||
private const val OUTPUT_DIR: String = "D:\\Project\\web\\PC\\auth\\auth-server\\services"
|
||||
|
||||
// 实体类名称
|
||||
private const val ENTITY: String = "Bunny"
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
generation("sys_email_template")
|
||||
generation("sys_power", "sys_role", "sys_role_power", "sys_user_role", "sys_router_power", "sys_router_role")
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,9 @@ class MyBatisPlusFieldConfig : MetaObjectHandler {
|
|||
* 使用mp做修改操作时候,这个方法执行
|
||||
*/
|
||||
override fun updateFill(metaObject: MetaObject) {
|
||||
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::class.java, LocalDateTime.now())
|
||||
this.strictUpdateFill(metaObject, "updateUser", Long::class.java, BaseContext.getUserId())
|
||||
if (BaseContext.getUserId() != null) {
|
||||
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::class.java, LocalDateTime.now())
|
||||
this.strictUpdateFill(metaObject, "updateUser", Long::class.java, BaseContext.getUserId())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ open class BaseContext {
|
|||
|
||||
// 用户id相关
|
||||
@JvmStatic
|
||||
fun getUserId(): Long {
|
||||
fun getUserId(): Long? {
|
||||
return userId.get()
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,10 @@ object JwtHelper {
|
|||
private const val TOKEN_EXPIRATION = (24 * 60 * 60 * 1000).toLong()
|
||||
|
||||
// JWT 的 秘钥
|
||||
private const val TOKEN_SIGN_KEY = "Bunny-Java-Template"
|
||||
private const val TOKEN_SIGN_KEY = "Bunny-Kotlin-Template"
|
||||
|
||||
// 默认主题
|
||||
private const val SUBJECT = "Bunny"
|
||||
private const val SUBJECT = "Bunny-Admin"
|
||||
|
||||
// 默认时间
|
||||
private val time = Date(System.currentTimeMillis() + TOKEN_EXPIRATION * 7)
|
||||
|
|
|
@ -4,26 +4,25 @@ import io.swagger.v3.oas.annotations.media.Schema
|
|||
import jakarta.validation.constraints.NotBlank
|
||||
import lombok.AllArgsConstructor
|
||||
import lombok.Builder
|
||||
import lombok.Data
|
||||
import lombok.NoArgsConstructor
|
||||
import lombok.experimental.Accessors
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Accessors(chain = true)
|
||||
@Schema(name = "LoginDto", title = "登录表单内容", description = "登录表单内容")
|
||||
class LoginDto {
|
||||
data class LoginDto(
|
||||
@Schema(name = "username", title = "用户名")
|
||||
var username: @NotBlank(message = "用户名不能为空") String? = null
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
var username: String? = null,
|
||||
|
||||
@Schema(name = "password", title = "密码")
|
||||
var password: @NotBlank(message = "密码不能为空") String? = null
|
||||
@NotBlank(message = "密码不能为空")
|
||||
var password: String? = null,
|
||||
|
||||
@Schema(name = "emailCode", title = "邮箱验证码")
|
||||
var emailCode: @NotBlank(message = "邮箱验证码不能为空") String? = null
|
||||
@NotBlank(message = "邮箱验证码不能为空")
|
||||
var emailCode: String? = null,
|
||||
|
||||
@Schema(name = "readMeDay", title = "记住我的天数")
|
||||
var readMeDay: Long = 7
|
||||
}
|
||||
var readMeDay: Long = 1,
|
||||
)
|
||||
|
|
|
@ -3,8 +3,6 @@ package cn.bunny.dao.entity.system
|
|||
import cn.bunny.dao.entity.BaseEntity
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import lombok.Getter
|
||||
import lombok.Setter
|
||||
import lombok.experimental.Accessors
|
||||
|
||||
/**
|
||||
|
@ -16,42 +14,40 @@ import lombok.experimental.Accessors
|
|||
* @author Bunny
|
||||
* @since 2024-09-26
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_user")
|
||||
@Schema(name = "AdminUser对象", title = "用户信息", description = "用户信息")
|
||||
class AdminUser : BaseEntity() {
|
||||
data class AdminUser(
|
||||
@Schema(name = "username", title = "用户名")
|
||||
var username: String? = null
|
||||
var username: String? = null,
|
||||
|
||||
@Schema(name = "nickName", title = "昵称")
|
||||
var nickName: String? = null
|
||||
var nickName: String? = null,
|
||||
|
||||
@Schema(name = "email", title = "邮箱")
|
||||
var email: String? = null
|
||||
var email: String? = null,
|
||||
|
||||
@Schema(name = "phone", title = "手机号")
|
||||
var phone: String? = null
|
||||
var phone: String? = null,
|
||||
|
||||
@Schema(name = "password", title = "密码")
|
||||
var password: String? = null
|
||||
var password: String? = null,
|
||||
|
||||
@Schema(name = "avatar", title = "头像")
|
||||
var avatar: String? = null
|
||||
var avatar: String? = null,
|
||||
|
||||
@Schema(name = "sex", title = "性别", description = "0:女 1:男")
|
||||
var sex: Byte? = null
|
||||
var sex: Byte? = null,
|
||||
|
||||
@Schema(name = "summary", title = "个人描述")
|
||||
var summary: String? = null
|
||||
var summary: String? = null,
|
||||
|
||||
@Schema(name = "lastLoginIp", title = "最后登录IP")
|
||||
var lastLoginIp: String? = null
|
||||
var lastLoginIp: String? = null,
|
||||
|
||||
@Schema(name = "lastLoginIpAddress", title = "最后登录ip归属地")
|
||||
var lastLoginIpAddress: String? = null
|
||||
var lastLoginIpAddress: String? = null,
|
||||
|
||||
@Schema(name = "status", title = "状态", description = "1:禁用 0:正常")
|
||||
var status: Byte? = null
|
||||
}
|
||||
var status: Byte? = null,
|
||||
) : BaseEntity()
|
||||
|
|
|
@ -3,8 +3,6 @@ package cn.bunny.dao.entity.system
|
|||
import cn.bunny.dao.entity.BaseEntity
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import lombok.Getter
|
||||
import lombok.Setter
|
||||
import lombok.experimental.Accessors
|
||||
|
||||
/**
|
||||
|
@ -16,24 +14,22 @@ import lombok.experimental.Accessors
|
|||
* @author Bunny
|
||||
* @since 2024-09-26
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_email_template")
|
||||
@Schema(name = "EmailTemplate对象", title = "邮件模板表", description = "邮件模板表")
|
||||
class EmailTemplate : BaseEntity() {
|
||||
data class EmailTemplate(
|
||||
@Schema(name = "email", title = "模板名称")
|
||||
var templateName: String? = null
|
||||
var templateName: String? = null,
|
||||
|
||||
@Schema(name = "subject", title = "主题")
|
||||
var subject: String? = null
|
||||
var subject: String? = null,
|
||||
|
||||
@Schema(name = "body", title = "邮件内容")
|
||||
var body: String? = null
|
||||
var body: String? = null,
|
||||
|
||||
@Schema(name = "type", title = "邮件类型")
|
||||
var type: String? = null
|
||||
var type: String? = null,
|
||||
|
||||
@Schema(name = "isDefault", title = "是否默认")
|
||||
var isDefault: Boolean? = null
|
||||
}
|
||||
var isDefault: Boolean? = null,
|
||||
) : BaseEntity()
|
||||
|
|
|
@ -3,7 +3,6 @@ package cn.bunny.dao.entity.system
|
|||
import cn.bunny.dao.entity.BaseEntity
|
||||
import com.baomidou.mybatisplus.annotation.TableName
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import lombok.Data
|
||||
import lombok.experimental.Accessors
|
||||
|
||||
/**
|
||||
|
@ -15,30 +14,28 @@ import lombok.experimental.Accessors
|
|||
* @author Bunny
|
||||
* @since 2024-09-26
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_email_users")
|
||||
@Schema(name = "EmailUsers对象", title = "邮箱发送表", description = "邮箱发送表")
|
||||
open class EmailUsers : BaseEntity() {
|
||||
|
||||
open class EmailUsers(
|
||||
@Schema(name = "email", title = "邮箱")
|
||||
var email: String? = null
|
||||
var email: String? = null,
|
||||
|
||||
@Schema(name = "emailTemplate", title = "使用邮件模板")
|
||||
var emailTemplate: Long? = null
|
||||
var emailTemplate: Long? = null,
|
||||
|
||||
@Schema(name = "password", title = "密码")
|
||||
var password: String? = null
|
||||
var password: String? = null,
|
||||
|
||||
@Schema(name = "host", title = "Host地址")
|
||||
var host: String? = null
|
||||
var host: String? = null,
|
||||
|
||||
@Schema(name = "port", title = "端口号")
|
||||
var port: Int? = null
|
||||
var port: Int? = null,
|
||||
|
||||
@Schema(name = "smtpAgreement", title = "邮箱协议")
|
||||
var smtpAgreement: String? = null
|
||||
var smtpAgreement: String? = null,
|
||||
|
||||
@Schema(name = "isDefault", title = "是否为默认邮件")
|
||||
var isDefault: Byte? = null
|
||||
}
|
||||
var isDefault: Byte? = null,
|
||||
) : BaseEntity()
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
package cn.bunny.dao.entity.system;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统菜单图标
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2024-09-26
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_menu_icon")
|
||||
@ApiModel(value = "MenuIcon对象", description = "系统菜单图标")
|
||||
public class MenuIcon implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("icon 名称")
|
||||
private String iconName;
|
||||
|
||||
@ApiModelProperty("创建用户")
|
||||
private Long createUser;
|
||||
|
||||
@ApiModelProperty("操作用户")
|
||||
private Long updateUser;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@ApiModelProperty("是否删除")
|
||||
private Byte isDeleted;
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
package cn.bunny.dao.entity.system;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统菜单表
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2024-09-26
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@TableName("sys_router")
|
||||
@ApiModel(value = "Router对象", description = "系统菜单表")
|
||||
public class Router implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("主键id")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("在项目中路径")
|
||||
private String routerPath;
|
||||
|
||||
@ApiModelProperty("路由名称")
|
||||
private String routeName;
|
||||
|
||||
@ApiModelProperty("父级id")
|
||||
private Long parentId;
|
||||
|
||||
@ApiModelProperty("路由title")
|
||||
private String title;
|
||||
|
||||
@ApiModelProperty("图标")
|
||||
private String icon;
|
||||
|
||||
@ApiModelProperty("等级")
|
||||
private Integer routerRank;
|
||||
|
||||
@ApiModelProperty("是否显示")
|
||||
private Boolean visible;
|
||||
|
||||
@ApiModelProperty("创建用户")
|
||||
private Long createUser;
|
||||
|
||||
@ApiModelProperty("操作用户")
|
||||
private Long updateUser;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty("更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@ApiModelProperty("是否删除")
|
||||
private Byte isDeleted;
|
||||
}
|
|
@ -3,21 +3,19 @@ package cn.bunny.dao.vo.email
|
|||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import lombok.AllArgsConstructor
|
||||
import lombok.Builder
|
||||
import lombok.Data
|
||||
import lombok.NoArgsConstructor
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "EmailTemplateVo对象", title = "邮箱模板返回内容", description = "邮箱模板返回内容")
|
||||
class EmailTemplateVo {
|
||||
data class EmailTemplateVo(
|
||||
@Schema(name = "templateName", title = "模板名称")
|
||||
var templateName: String? = null
|
||||
var templateName: String? = null,
|
||||
|
||||
@Schema(name = "subject", title = "主题")
|
||||
var subject: String? = null
|
||||
var subject: String? = null,
|
||||
|
||||
@Schema(name = "body", title = "邮件内容")
|
||||
var body: String? = null
|
||||
}
|
||||
var body: String? = null,
|
||||
)
|
|
@ -2,57 +2,63 @@ package cn.bunny.dao.vo.user
|
|||
|
||||
import cn.bunny.dao.vo.BaseVo
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import lombok.*
|
||||
import lombok.AllArgsConstructor
|
||||
import lombok.Builder
|
||||
import lombok.NoArgsConstructor
|
||||
|
||||
/**
|
||||
* 用户登录返回内容
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "LoginVo对象", title = "登录成功返回内容", description = "登录成功返回内容")
|
||||
class LoginVo : BaseVo() {
|
||||
data class LoginVo(
|
||||
@Schema(name = "username", title = "用户名")
|
||||
var username: String? = null
|
||||
var username: String? = null,
|
||||
|
||||
@Schema(name = "nickName", title = "昵称")
|
||||
var nickName: String? = null
|
||||
var nickName: String? = null,
|
||||
|
||||
@Schema(name = "email", title = "邮箱")
|
||||
var email: String? = null
|
||||
var email: String? = null,
|
||||
|
||||
@Schema(name = "phone", title = "手机号")
|
||||
var phone: String? = null
|
||||
var phone: String? = null,
|
||||
|
||||
@Schema(name = "password", title = "密码")
|
||||
var password: String? = null
|
||||
var password: String? = null,
|
||||
|
||||
@Schema(name = "avatar", title = "头像")
|
||||
var avatar: String? = null
|
||||
var avatar: String? = null,
|
||||
|
||||
@Schema(name = "sex", title = "性别", description = "0:女 1:男")
|
||||
var sex: Byte? = null
|
||||
var sex: Byte? = null,
|
||||
|
||||
@Schema(name = "summary", title = "个人描述")
|
||||
var summary: String? = null
|
||||
var summary: String? = null,
|
||||
|
||||
@Schema(name = "lastLoginIp", title = "最后登录IP")
|
||||
var lastLoginIp: String? = null
|
||||
var lastLoginIp: String? = null,
|
||||
|
||||
@Schema(name = "lastLoginIpAddress", title = "最后登录ip归属地")
|
||||
var lastLoginIpAddress: String? = null
|
||||
var lastLoginIpAddress: String? = null,
|
||||
|
||||
@Schema(name = "status", title = "状态", description = "1:禁用 0:正常")
|
||||
var status: Byte? = null
|
||||
var status: Byte? = null,
|
||||
|
||||
@Schema(name = "token", title = "令牌")
|
||||
var token: String? = null
|
||||
var token: String? = null,
|
||||
|
||||
@Schema(name = "refreshToken", title = "刷新token")
|
||||
var refreshToken: String? = null,
|
||||
|
||||
@Schema(name = "expires", title = "过期时间")
|
||||
var expires: Long? = null,
|
||||
|
||||
@Schema(name = "roleList", title = "角色列表")
|
||||
var roleList: List<String>? = null
|
||||
var roleList: List<String>? = null,
|
||||
|
||||
@Schema(name = "powerList", title = "权限列表")
|
||||
var powerList: List<String>? = null
|
||||
}
|
||||
var powerList: List<String>? = null,
|
||||
) : BaseVo()
|
||||
|
|
|
@ -11,10 +11,10 @@ import lombok.NoArgsConstructor
|
|||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(name = "ValidateCodeVo", title = "验证码响应结果实体类", description = "验证码响应结果实体类")
|
||||
class ValidateCodeVo {
|
||||
class ValidateCodeVo(
|
||||
@Schema(name = "codeKey", title = "验证码key")
|
||||
var codeKey: String? = null
|
||||
var codeKey: String? = null,
|
||||
|
||||
@Schema(name = "codeValue", title = "验证码value")
|
||||
var codeValue: String? = null
|
||||
}
|
||||
var codeValue: String? = null,
|
||||
)
|
|
@ -39,6 +39,10 @@
|
|||
<artifactId>common-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<!-- spring-security -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -49,15 +53,6 @@
|
|||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
</dependency>
|
||||
<!-- amqp -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.amqp</groupId>
|
||||
<artifactId>spring-rabbit-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
|
@ -72,11 +67,6 @@
|
|||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
</dependency>
|
||||
<!-- websocket -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
<!-- 多数据库源插件 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
|
|
|
@ -3,13 +3,15 @@ package cn.bunny.services.factory
|
|||
import cn.bunny.common.service.utils.JwtHelper
|
||||
import cn.bunny.common.service.utils.ip.IpUtil
|
||||
import cn.bunny.dao.entity.system.AdminUser
|
||||
import cn.bunny.dao.entity.system.Power
|
||||
import cn.bunny.dao.entity.system.Role
|
||||
import cn.bunny.dao.pojo.constant.RedisUserConstant.Companion.getAdminLoginInfoPrefix
|
||||
import cn.bunny.dao.pojo.constant.RedisUserConstant.Companion.getAdminUserEmailCodePrefix
|
||||
import cn.bunny.dao.vo.user.LoginVo
|
||||
import cn.bunny.services.mapper.UserMapper
|
||||
import cn.bunny.services.mapper.PowerMapper
|
||||
import cn.bunny.services.mapper.RoleMapper
|
||||
import org.springframework.beans.BeanUtils
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.data.redis.core.RedisTemplate
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
|
@ -18,17 +20,20 @@ import java.util.concurrent.TimeUnit
|
|||
@Component
|
||||
@Transactional
|
||||
class UserFactory {
|
||||
@Qualifier("redisTemplate")
|
||||
@Autowired
|
||||
private lateinit var powerMapper: PowerMapper
|
||||
|
||||
@Autowired
|
||||
private lateinit var roleMapper: RoleMapper
|
||||
|
||||
@Autowired
|
||||
private lateinit var redisTemplate: RedisTemplate<Any, Any>
|
||||
|
||||
@Autowired
|
||||
private lateinit var userMapper: UserMapper
|
||||
|
||||
fun buildUserVo(user: AdminUser, readMeDay: Long): LoginVo {
|
||||
// 创建token
|
||||
val userId = user.id
|
||||
val token = JwtHelper.createToken(userId, user.email, readMeDay.toInt())
|
||||
val userId = user.id!!
|
||||
val email = user.email!!
|
||||
val token = JwtHelper.createToken(userId, email, readMeDay.toInt())
|
||||
|
||||
// 设置用户IP地址,并更新用户信息
|
||||
val updateUser = AdminUser()
|
||||
|
@ -40,17 +45,19 @@ class UserFactory {
|
|||
val loginVo = LoginVo()
|
||||
BeanUtils.copyProperties(user, loginVo)
|
||||
loginVo.token = token
|
||||
loginVo.refreshToken = token
|
||||
loginVo.lastLoginIp = IpUtil.getCurrentUserIpAddress().remoteAddr
|
||||
loginVo.lastLoginIpAddress = IpUtil.getCurrentUserIpAddress().ipRegion
|
||||
// TODO 设置权限和角色内容
|
||||
loginVo.roleList = listOf("admin", "common")
|
||||
loginVo.powerList = listOf("*.*")
|
||||
loginVo.roleList = roleMapper.selectListByUserId(userId).map { role: Role -> role.roleCode!! }
|
||||
loginVo.powerList = powerMapper.selectListByUserId(userId).map { power: Power -> power.powerCode!! }
|
||||
loginVo.updateUser = userId
|
||||
loginVo.expires = readMeDay
|
||||
|
||||
// 将信息保存在Redis中
|
||||
redisTemplate.opsForValue().set(getAdminLoginInfoPrefix(user.email!!), loginVo, readMeDay, TimeUnit.DAYS)
|
||||
redisTemplate.opsForValue().set(getAdminLoginInfoPrefix(email), loginVo, readMeDay, TimeUnit.DAYS)
|
||||
|
||||
// 将Redis中验证码删除
|
||||
redisTemplate.delete(getAdminUserEmailCodePrefix(user.email!!))
|
||||
redisTemplate.delete(getAdminUserEmailCodePrefix(email))
|
||||
|
||||
return loginVo
|
||||
}
|
||||
|
|
|
@ -29,22 +29,22 @@ import org.springframework.security.web.util.matcher.RegexRequestMatcher
|
|||
@EnableMethodSecurity
|
||||
class WebSecurityConfig {
|
||||
@Autowired
|
||||
private val redisTemplate: RedisTemplate<Any, Any>? = null
|
||||
private lateinit var redisTemplate: RedisTemplate<Any, Any?>
|
||||
|
||||
// 自定义用户接口
|
||||
@Autowired
|
||||
private val customUserDetailsService: CustomUserDetailsService? = null
|
||||
private lateinit var customUserDetailsService: CustomUserDetailsService
|
||||
|
||||
// 自定义密码加密器
|
||||
@Autowired
|
||||
private val customPasswordEncoder: CustomPasswordEncoder? = null
|
||||
private lateinit var customPasswordEncoder: CustomPasswordEncoder
|
||||
|
||||
// 自定义验证码
|
||||
@Autowired
|
||||
private val customAuthorizationManager: CustomAuthorizationManagerServiceImpl? = null
|
||||
private lateinit var customAuthorizationManager: CustomAuthorizationManagerServiceImpl
|
||||
|
||||
@Autowired
|
||||
private val authenticationConfiguration: AuthenticationConfiguration? = null
|
||||
private lateinit var authenticationConfiguration: AuthenticationConfiguration
|
||||
|
||||
@Bean
|
||||
@Throws(Exception::class)
|
||||
|
@ -71,13 +71,12 @@ class WebSecurityConfig {
|
|||
exception.accessDeniedHandler(SecurityAccessDeniedHandler())
|
||||
} // 登录验证过滤器
|
||||
.addFilterBefore(
|
||||
TokenLoginFilterService(authenticationConfiguration!!, redisTemplate!!, customUserDetailsService!!),
|
||||
TokenLoginFilterService(authenticationConfiguration, redisTemplate, customUserDetailsService),
|
||||
UsernamePasswordAuthenticationFilter::class.java
|
||||
) // 其它权限鉴权过滤器
|
||||
.addFilterAt(
|
||||
TokenAuthenticationFilter(redisTemplate),
|
||||
UsernamePasswordAuthenticationFilter::class.java
|
||||
) // 自定义密码加密器和用户登录
|
||||
)
|
||||
// 其它权限鉴权过滤器
|
||||
.addFilterAt(TokenAuthenticationFilter(redisTemplate), UsernamePasswordAuthenticationFilter::class.java)
|
||||
// 自定义密码加密器和用户登录
|
||||
.passwordManagement(customPasswordEncoder).userDetailsService(customUserDetailsService)
|
||||
|
||||
return httpSecurity.build()
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.springframework.web.filter.OncePerRequestFilter
|
|||
import java.io.IOException
|
||||
import java.util.function.Consumer
|
||||
|
||||
class TokenAuthenticationFilter(private val redisTemplate: RedisTemplate<Any, Any>) : OncePerRequestFilter() {
|
||||
class TokenAuthenticationFilter(private val redisTemplate: RedisTemplate<Any, Any?>) : OncePerRequestFilter() {
|
||||
@Throws(ServletException::class, IOException::class, BunnyException::class)
|
||||
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
|
||||
val token = request.getHeader("token")
|
||||
|
|
|
@ -31,10 +31,10 @@ import java.util.*
|
|||
*/
|
||||
class TokenLoginFilterService(
|
||||
authenticationConfiguration: AuthenticationConfiguration,
|
||||
redisTemplate: RedisTemplate<Any, Any>,
|
||||
customUserDetailsService: CustomUserDetailsService
|
||||
redisTemplate: RedisTemplate<Any, Any?>,
|
||||
customUserDetailsService: CustomUserDetailsService,
|
||||
) : UsernamePasswordAuthenticationFilter() {
|
||||
private val redisTemplate: RedisTemplate<Any, Any>
|
||||
private val redisTemplate: RedisTemplate<Any, Any?>
|
||||
private val customUserDetailsService: CustomUserDetailsService
|
||||
private lateinit var loginDto: LoginDto
|
||||
|
||||
|
@ -66,11 +66,17 @@ class TokenLoginFilterService(
|
|||
val password = loginDto.password
|
||||
|
||||
// 获取Redis中邮箱验证码,并判断是否存在或过期
|
||||
val redisEmailCode = redisTemplate.opsForValue()[getAdminUserEmailCodePrefix(username!!)]
|
||||
redisEmailCode ?: out(response, Result.error(ResultCodeEnum.EMAIL_CODE_EMPTY))
|
||||
val redisEmailCode = redisTemplate.opsForValue().get(getAdminUserEmailCodePrefix(username!!))
|
||||
if (redisEmailCode == null) {
|
||||
out(response, Result.error(ResultCodeEnum.EMAIL_CODE_EMPTY))
|
||||
return null
|
||||
}
|
||||
|
||||
// 判断邮箱验证码是否和用户传入的验证码一致
|
||||
if (emailCode != redisEmailCode?.toString()?.lowercase()) out(response, Result.error(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING))
|
||||
if (emailCode != redisEmailCode.toString().lowercase()) {
|
||||
out(response, Result.error(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING))
|
||||
return null
|
||||
}
|
||||
|
||||
// 封装对象,将用户名传入
|
||||
val authenticationToken: Authentication = UsernamePasswordAuthenticationToken(username, password)
|
||||
|
@ -103,7 +109,7 @@ class TokenLoginFilterService(
|
|||
override fun unsuccessfulAuthentication(
|
||||
request: HttpServletRequest,
|
||||
response: HttpServletResponse,
|
||||
failed: AuthenticationException
|
||||
failed: AuthenticationException,
|
||||
) {
|
||||
val password = loginDto.password
|
||||
val username = loginDto.username
|
||||
|
|
|
@ -3,9 +3,11 @@ package cn.bunny.services.security.service.impl
|
|||
import cn.bunny.common.service.exception.BunnyException
|
||||
import cn.bunny.dao.dto.system.LoginDto
|
||||
import cn.bunny.dao.entity.system.AdminUser
|
||||
import cn.bunny.dao.entity.system.Role
|
||||
import cn.bunny.dao.pojo.result.ResultCodeEnum
|
||||
import cn.bunny.dao.vo.user.LoginVo
|
||||
import cn.bunny.services.factory.UserFactory
|
||||
import cn.bunny.services.mapper.RoleMapper
|
||||
import cn.bunny.services.mapper.UserMapper
|
||||
import cn.bunny.services.security.custom.CustomUser
|
||||
import cn.bunny.services.security.service.CustomUserDetailsService
|
||||
|
@ -19,26 +21,27 @@ import org.springframework.util.DigestUtils
|
|||
|
||||
@Component
|
||||
class CustomUserDetailsServiceImpl : CustomUserDetailsService {
|
||||
@Autowired
|
||||
private lateinit var roleMapper: RoleMapper
|
||||
|
||||
@Autowired
|
||||
private lateinit var userFactory: UserFactory
|
||||
|
||||
@Autowired
|
||||
private lateinit var userMapper: UserMapper
|
||||
|
||||
|
||||
@Throws(UsernameNotFoundException::class)
|
||||
override fun loadUserByUsername(username: String): UserDetails {
|
||||
// 查询用户相关内容
|
||||
val queryWrapper = KtQueryWrapper(AdminUser()).eq(AdminUser::email, username)
|
||||
.or()
|
||||
.eq(AdminUser::username, username)
|
||||
val queryWrapper = KtQueryWrapper(AdminUser()).eq(AdminUser::email, username).or().eq(AdminUser::username, username)
|
||||
|
||||
// 根据邮箱查询用户名
|
||||
val user = userMapper.selectOne(queryWrapper)
|
||||
user ?: throw UsernameNotFoundException("")
|
||||
user ?: throw UsernameNotFoundException("用户不存在 ")
|
||||
|
||||
// TODO 查询所有的角色
|
||||
return CustomUser(user, AuthorityUtils.createAuthorityList(listOf("admin", "common")))
|
||||
// 根据用户id查询当前用户所有角色
|
||||
val roleList: List<Role> = roleMapper.selectListByUserId(user.id!!)
|
||||
return CustomUser(user, AuthorityUtils.createAuthorityList(roleList.map { role -> role.roleCode }))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,8 +51,7 @@ class CustomUserDetailsServiceImpl : CustomUserDetailsService {
|
|||
* @return 登录后结果返回
|
||||
*/
|
||||
override fun login(loginDto: LoginDto): LoginVo {
|
||||
val username = loginDto.username
|
||||
val password = loginDto.password
|
||||
val (username, password, _, readMeDay) = loginDto
|
||||
|
||||
// 查询用户相关内容
|
||||
val queryWrapper = KtQueryWrapper(AdminUser()).eq(AdminUser::email, username).or()
|
||||
|
@ -60,6 +62,6 @@ class CustomUserDetailsServiceImpl : CustomUserDetailsService {
|
|||
val md5Password: String = DigestUtils.md5DigestAsHex(password!!.byteInputStream())
|
||||
if (!user.password.equals(md5Password)) throw BunnyException(ResultCodeEnum.LOGIN_ERROR)
|
||||
|
||||
return userFactory.buildUserVo(user, loginDto.readMeDay)
|
||||
return userFactory.buildUserVo(user, readMeDay)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue