SpringBoot优点达项目实战:登录功能实现(四)
文章目录
1、查看接口
POST /index/login
Body 请求参数
{"login_name":"admin","password":"111111"}
请求参数
名称位置类型必选说明x-tokenheaderstringtruetoken字符串bodybodyobjectfalsenone» login_namebodystringtrue可用 admin» passwordbodystringtrue可用 111111
返回示例
{"errno":0,"errmsg":null,,"data":{"token":"eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2NjgwMDYwMTgsInJvbGRJZCI6IltcIjFjNTRlMDAzYzFmYzRkY2Q5YjA4N2VmOGQ0OGFiYWMzXCJdIiwidXNlcklkIjoiMSJ9.mi50Gskw6sV1H-3RPKasO9f_zFw-PgE0VGItvtxxGE1bO9iXer-48i8OCZZtUsJKohX1u0a2r6eFR5e6wRWT8Q"}}
返回结果
名称类型必须说明»errnoIntegertrue编码: 0成功,1失败»errmsgStringtrue消息»dataObjecttrue响应数据»»»tokenStringfalse登录成功后的唯一标识
2、查看数据库

从password字段可以看出来,密码是进行加密的
3、代码实现
1、创建实体类
@Data@TableName("sys_user")publicclassSystemUser{@Schema(description ="用户id")@TableId(value ="id")privateString id;@Schema(description ="登录账号")@TableField(value ="login_name")@JsonProperty("login_name")privateString loginName;@Schema(description ="用户密码")@TableField(value ="password")privateString password;@Schema(description ="用户名称")@TableField(value ="name")privateString name;@Schema(description ="邮箱")@TableField("email")privateString email;@Schema(description ="手机")@TableField(value ="phone")privateString phone;@Schema(description ="登录时间")@TableField(value ="login_date")privateDate loginDate;@Schema(description ="创建时间")@TableField(value ="create_date",fill =FieldFill.INSERT)@JsonIgnoreprivateDate createDate;@Schema(description ="修改时间")@TableField(value ="update_date",fill =FieldFill.UPDATE)@JsonIgnoreprivateDate updateDate;@Schema(description ="逻辑删除")@TableLogic()@TableField("del_flag")@JsonIgnoreprivateInteger delFlag;@Schema(description ="职位id")@TableField(value ="role_id")privateString roleId;@Schema(description ="状态")@TableField(value ="status")privateBaseStatus status;@Schema(description ="默认数据")@TableField(value ="default_data")privateString defaultData;}
- @Data:这是 Lombok 提供的注解,用于自动生成该类的 getter、setter、toString、equals 和 hashCode 方法。
- @TableName(“sys_user”):这是 MyBatis-Plus 提供的注解,用于指定该类对应的数据库表名
sys_user。 - @Schema:用于生成 API 文档时描述字段。
- @TableId 和 @TableField:用于指定数据库表中的列名和属性。
- @JsonProperty 和 @JsonIgnore:用于控制 JSON 序列化和反序列化行为。
- @TableLogic:用于实现逻辑删除
2、controller实现
@PostMapping("/login")@Operation(summary ="后台登录")publicStringlogin(@RequestBodySystemUser systemUser){
log.info("用户登录{}",systemUser);String result = systemConfigService.login(systemUser);return result;}
- 接收客户端发送的 POST 请求,路径为
/login。 - 将请求体中的 JSON 数据反序列化为
SystemUser对象。 - 记录登录信息到日志中。
- 调用
systemConfigService的login方法进行登录逻辑处理。 - 返回登录结果
3、service层实现
service接口
定义操作SysUser的service
/**
* 针对system_user表的用户操作
*/publicinterfaceSystemUserServiceextendsIService<SystemUser>{}
定义操作SysUser的serviceImpl
@Service@Slf4jpublicclassSystemUserServiceImplextendsServiceImpl<SystemUserMapper,SystemUser>implementsSystemUserService{}
在SysconfigService中获取
/**
* 用户等登录
* @param systemUser
* @return
*/Stringlogin(SystemUser systemUser);
在实现类中进行业务处理
@AutowiredprivateSystemUserService userService;/**
* 用户登录
*
* @param systemUser
* @return
*/@OverridepublicStringlogin(SystemUser systemUser){String name = systemUser.getLoginName();String password = systemUser.getPassword();//判断用户是否输入账号if(name ==null){thrownewyoudiandaException(ResultCodeEnum.ADMIN_LOGIN_USER_NULL);}//判断用户是否输入密码if(password ==null){thrownewyoudiandaException(ResultCodeEnum.ADMIN_LOGIN_PASSWORD_NULL);}//查询用户LambdaQueryWrapper<SystemUser> queryWrapper =newLambdaQueryWrapper<>();
queryWrapper.eq(SystemUser::getLoginName,name);SystemUser user = userService.getOne(queryWrapper);if(user ==null){thrownewyoudiandaException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);}//查询用户是否可用if(user.getStatus()==BaseStatus.DISABLE){thrownewyoudiandaException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);}//查看密码是否正确if(!user.getPassword().equals(DigestUtils.md5Hex(password))){
log.info(DigestUtils.md5Hex(user.getPassword()));thrownewyoudiandaException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);}// 生成 JWTString token =JwtUtil.createToken(Long.valueOf(user.getId()), user.getName());// 构建响应数据Map<String,Object> data =newHashMap<>();
data.put("token", token);Map<String,Object> response =newHashMap<>();
response.put("errno",0);
response.put("errmsg",null);
response.put("data", data);try{// 将响应数据转换为 JSON 字符串ObjectMapper objectMapper =newObjectMapper();return objectMapper.writeValueAsString(response);}catch(Exception e){
e.printStackTrace();return"{\"errno\": 1, \"errmsg\": \"Error generating token\"}";}}
这个
login
方法实现了用户登录的完整逻辑:
- 验证用户输入的登录名和密码。
- 查询用户是否存在。
- 检查用户状态是否可用。
- 验证用户密码是否正确。
- 生成 JWT 令牌。
- 构建并返回包含令牌的 JSON 响应。
生成JWT令牌
在common模块中定义工具类,进行令牌生成
publicclassJwtUtil{privatestaticSecretKey secretKey =Keys.hmacShaKeyFor("WyjcDMViPOOsizAdpbrgtbhSXxZBYfns".getBytes());publicstaticStringcreateToken(Long userId,String username){String jwt =Jwts.builder().setExpiration(newDate(System.currentTimeMillis()+36000000)).setSubject("LOGIN_USER").claim("userId", userId).claim("username", username).signWith(secretKey,SignatureAlgorithm.HS256).compact();return jwt;}}
JwtUtil
用于生成 JSON Web Token (JWT),主要包含一个静态方法
createToken
,该方法接收用户 ID 和用户名,并生成一个包含这些信息的 JWT。
- secretKey:这是一个静态的
SecretKey对象,用于签署 JWT。它是使用Keys.hmacShaKeyFor方法生成的,参数是一个字节数组,这里是字符串"WyjcDMViPOOsizAdpbrgtbhSXxZBYfns"的字节表示。 - setExpiration:设置 JWT 的过期时间,这里设置为当前时间加上 10 小时(36000000 毫秒)。
- setSubject:设置 JWT 的主题,这里设置为
"LOGIN_USER"。 - claim:添加自定义声明(claims),这里添加了用户 ID (
userId) 和用户名 (username)。 - signWith:使用指定的
secretKey和签名算法(HS256)对 JWT 进行签名。 - compact:生成并返回 JWT 字符串。
业务处理中用到了一些异常,在此之前应该定义异常类
在common模块中定义
@Datapublicclass youdiandaException extendsRuntimeException{//异常状态码privateInteger code;publicyoudiandaException(String message,Integer code){super(message);this.code = code;}/**
* 根据响应结果枚举对象创建异常对象
*/publicyoudiandaException(ResultCodeEnum resultCodeEnum){super(resultCodeEnum.getMessage());this.code = resultCodeEnum.getCode();}}
同时在model模块中创建枚举类统一返回的信息
/**
* 统一返回结果状态信息类
*/@GetterpublicenumResultCodeEnum{LOGIN_SUCCESS(0,"登录成功"),LOGIN_FAIL(1,"登录失败"),SUCCESS(200,"成功"),FAIL(201,"失败"),PARAM_ERROR(202,"参数不正确"),SERVICE_ERROR(203,"服务异常"),DATA_ERROR(204,"数据异常"),ILLEGAL_REQUEST(205,"非法请求"),REPEAT_SUBMIT(206,"重复提交"),ADMIN_LOGIN_AUTH(305,"未登陆"),ADMIN_ACCOUNT_NOT_EXIST_ERROR(306,"账号不存在"),ADMIN_ACCOUNT_ERROR(307,"用户名或密码错误"),ADMIN_ACCOUNT_DISABLED_ERROR(308,"该用户已被禁用"),ADMIN_ACCESS_FORBIDDEN(309,"无访问权限"),ADMIN_LOGIN_USER_NULL(310,"请输入用户"),ADMIN_LOGIN_PASSWORD_NULL(311,"请输入密码"),TOKEN_EXPIRED(601,"token过期"),TOKEN_INVALID(602,"token非法");privatefinalInteger code;privatefinalString message;ResultCodeEnum(Integer code,String message){this.code = code;this.message = message;}}
4、Mapper层
@MapperpublicinterfaceSystemUserMapperextendsBaseMapper<SystemUser>{}
因为业务层中使用的是mybatisPlus自带的查询语句,所以Mapper层不需要去进行sql自定义查询,但必须将创建出来,为业务层实现
4、测试
在knife4j进行调试

版权归原作者 小林学习编程 所有, 如有侵权,请联系我们删除。