SpringBoot优点达项目实战:登录功能实现(四)

SpringBoot优点达项目实战:登录功能实现(四)


文章目录

      • SpringBoot优点达项目实战:登录功能实现(四)
        • 1、查看接口
        • 2、查看数据库
        • 3、代码实现
          • 1、创建实体类
          • 2、controller实现
          • 3、service层实现
          • 4、Mapper层
        • 4、测试

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、查看数据库

image-20240626175336719

从password字段可以看出来,密码是进行加密的

3、代码实现
1、创建实体类
@Data
@TableName("sys_user")
public class SystemUser {

    @Schema(description = "用户id")
    @TableId(value = "id")
    private String id;

    @Schema(description = "登录账号")
    @TableField(value = "login_name")
    @JsonProperty("login_name")
    private String loginName;

    @Schema(description = "用户密码")
    @TableField(value = "password")
    private String password;

    @Schema(description = "用户名称")
    @TableField(value = "name")
    private String name;

    @Schema(description = "邮箱")
    @TableField("email")
    private String email;

    @Schema(description = "手机")
    @TableField(value = "phone")
    private String phone;

    @Schema(description = "登录时间")
    @TableField(value = "login_date")
    private Date loginDate;

    @Schema(description = "创建时间")
    @TableField(value = "create_date",fill = FieldFill.INSERT)
    @JsonIgnore
    private Date createDate;

    @Schema(description = "修改时间")
    @TableField(value = "update_date",fill = FieldFill.UPDATE)
    @JsonIgnore
    private Date updateDate;

    @Schema(description = "逻辑删除")
    @TableLogic()
    @TableField("del_flag")
    @JsonIgnore
    private Integer delFlag;

    @Schema(description = "职位id")
    @TableField(value = "role_id")
    private String roleId;

    @Schema(description = "状态")
    @TableField(value = "status")
    private BaseStatus status;

    @Schema(description = "默认数据")
    @TableField(value = "default_data")
    private String 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 = "后台登录")
public String login(@RequestBody SystemUser systemUser){
    log.info("用户登录{}",systemUser);
    String result = systemConfigService.login(systemUser);
    return result;
}
  1. 接收客户端发送的 POST 请求,路径为 /login
  2. 将请求体中的 JSON 数据反序列化为 SystemUser 对象。
  3. 记录登录信息到日志中。
  4. 调用 systemConfigServicelogin 方法进行登录逻辑处理。
  5. 返回登录结果
3、service层实现

service接口

定义操作SysUser的service

/**
 * 针对system_user表的用户操作
 */
public interface SystemUserService extends IService<SystemUser> {
}

定义操作SysUser的serviceImpl

@Service
@Slf4j
public class SystemUserServiceImpl extends ServiceImpl<SystemUserMapper, SystemUser>
implements SystemUserService {
}

在SysconfigService中获取

    /**
     * 用户等登录
     * @param systemUser
     * @return
     */
    String login(SystemUser systemUser);

在实现类中进行业务处理

@Autowired
private SystemUserService userService;

/**
     * 用户登录
     *
     * @param systemUser
     * @return
     */
@Override
public String login(SystemUser systemUser) {
    String name = systemUser.getLoginName();
    String password = systemUser.getPassword();
    //判断用户是否输入账号
    if (name == null){
        throw new youdiandaException(ResultCodeEnum.ADMIN_LOGIN_USER_NULL);
    }
    //判断用户是否输入密码
    if (password == null){
        throw new youdiandaException(ResultCodeEnum.ADMIN_LOGIN_PASSWORD_NULL);
    }

    //查询用户
    LambdaQueryWrapper<SystemUser> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SystemUser::getLoginName,name);
    SystemUser user = userService.getOne(queryWrapper);
    if (user == null){
        throw new youdiandaException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);
    }

    //查询用户是否可用
    if (user.getStatus() == BaseStatus.DISABLE){
        throw new youdiandaException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);
    }

    //查看密码是否正确
    if (!user.getPassword().equals(DigestUtils.md5Hex(password))){
        log.info(DigestUtils.md5Hex(user.getPassword()));
        throw new youdiandaException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);
    }

    // 生成 JWT
    String token = JwtUtil.createToken(Long.valueOf(user.getId()), user.getName());

    // 构建响应数据
    Map<String, Object> data = new HashMap<>();
    data.put("token", token);

    Map<String, Object> response = new HashMap<>();
    response.put("errno", 0);
    response.put("errmsg", null);
    response.put("data", data);

    try {
        // 将响应数据转换为 JSON 字符串
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.writeValueAsString(response);
    } catch (Exception e) {
        e.printStackTrace();
        return "{\"errno\": 1, \"errmsg\": \"Error generating token\"}";
    }
}

这个 login 方法实现了用户登录的完整逻辑:

  1. 验证用户输入的登录名和密码。
  2. 查询用户是否存在。
  3. 检查用户状态是否可用。
  4. 验证用户密码是否正确。
  5. 生成 JWT 令牌。
  6. 构建并返回包含令牌的 JSON 响应。

生成JWT令牌

在common模块中定义工具类,进行令牌生成

public class JwtUtil {
    private static SecretKey secretKey = Keys.hmacShaKeyFor("WyjcDMViPOOsizAdpbrgtbhSXxZBYfns".getBytes());

    public static String createToken(Long userId,String username){
        String jwt = Jwts.builder()
                .setExpiration(new Date(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模块中定义

@Data
public class youdiandaException extends RuntimeException{

    //异常状态码
    private Integer code;

    public youdiandaException(String message,Integer code){
        super(message);
        this.code = code;
    }

    /**
     * 根据响应结果枚举对象创建异常对象
     */
    public youdiandaException(ResultCodeEnum resultCodeEnum){
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }
}

同时在model模块中创建枚举类统一返回的信息

/**
 * 统一返回结果状态信息类
 */
@Getter
public enum ResultCodeEnum {

    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非法");

    private final Integer code;

    private final String message;

    ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

4、Mapper层
@Mapper
public interface SystemUserMapper extends BaseMapper<SystemUser> {
}

因为业务层中使用的是mybatisPlus自带的查询语句,所以Mapper层不需要去进行sql自定义查询,但必须将创建出来,为业务层实现

4、测试

在knife4j进行调试

image-20240626181358834

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/747717.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM专题十二:JVM 中的收集器二

上一篇JVM专题十一&#xff1a;JVM 中的收集器一咱们介绍了垃圾收集器的分类&#xff0c;已经主流的分代垃圾收集器重点看了CMS与三色标记算法&#xff0c;本篇咱们继续来看意G1、ZGC等。 G1收集器 G1&#xff08;Garbage-First Garbage Collector&#xff09;是一种服务器端的…

React实现二级评论

1. 什么是二级评论 图片来源–blackfrog的掘金文章 口语化的讲当我发布一个评论的时候就是一级评论&#xff0c;当我回复我发布的评论的时候就是二级评论并且将所有回复二级评论的评论也归于二级评论。 2. 二级评论功能的实现逻辑 在这里后端设计了四个接口分别是 获取所有…

千呼新零售2.0-OCR拍照识别采购单

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物、中医养生、大健康等连锁店…

目标检测系列(四)利用pyqt5实现yolov8目标检测GUI界面

目录 1、pyqt5安装 2、PyCharm添加Qt Designer、PyUIC 3、Qt Designer设计界面 4、根据ui文件自动生成py文件 5、修改py文件来调用检测程序 6、执行py文件启动 1、pyqt5安装 Qt Designer&#xff1a;一个用于创建图形用户界面的工具&#xff0c;可轻松构建复杂的用户界面…

ChatUI:使用Gradio.NET为LLamaWorker快速创建大模型演示界面

Gradio.NET 是 Gradio 的.NET 移植版本。它是一个能够助力迅速搭建机器学习模型演示界面的库&#xff0c;其提供了简洁的 API&#xff0c;仅需寥寥数行代码就能创建出一个具备交互性的界面。在本篇文章中&#xff0c;我们将会阐述如何借助 Gradio.NET 为 LLamaWorker 快捷地创建…

Python 基础 (标准库):堆 heap

1. 官方文档 heapq --- 堆队列算法 — Python 3.12.4 文档 2. 相关概念 堆 heap 是一种具体的数据结构&#xff08;concrete data structures&#xff09;&#xff1b;优先级队列 priority queue 是一种抽象的数据结构&#xff08;abstract data structures&#xff09;&…

【数据结构】——链表经典OJ(leetcode)

文章目录 一、 相交链表二、 反转链表三、 回文链表四、 环形链表五、 环形链表 II六、 合并两个有序链表七、 两数相加八、 删除链表的倒数第N个节点九、 随机链表的复制 一、 相交链表 双指针法 struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListN…

MySQL进阶-索引-使用规则-最左前缀法则和范围查询

文章目录 1、最左前缀法则2、启动mysql3、查询tb_user4、查看tb_user的索引5、执行计划 profession 软件工程 and age31 and status 06、执行计划 profession 软件工程 and age317、执行计划 profession 软件工程8、执行计划 age31 and status 09、执行计划 status 010、执行…

直流电机双闭环调速Simulink仿真

直流电机参数&#xff1a; 仿真模型算法介绍&#xff1a; 1&#xff09;三相整流桥&#xff0c;采用半控功率器件SCR晶闸管&#xff1b; 2&#xff09;采用转速环、电流环 双闭环控制算法&#xff1b; 3&#xff09;外环-转速环&#xff0c;采用PI 比例积分控制&#xff1b;…

通信系统网络架构_3.移动通信网络架构

移动通信网为移动互联网提供了强有力的支持&#xff0c;尤其是5G网络为个人用户、垂直行业等提供了多样化的服务。以下从业务应用角度给出面向5G网络的组网方式。 1.5GS与DN互连 5GS&#xff08;5G System&#xff09;在为移动终端用户&#xff08;User Equipment&#xff0c;…

搜维尔科技:【研究】触觉手套比控制器更能带来身临其境、更安全、更高效的虚拟体验

自然交互可提高VR模拟的有效性。研究表明&#xff0c;触觉手套比控制器更能带来身临其境、更安全、更高效的虚拟体验。 以下是验证 医疗培训中的触觉技术 “ 95.5%的参与者表示触摸是 XR 教育的重要组成部分&#xff0c;90.9% 的参与者表示 XR 触觉将提供一个安全的学习场所。…

eNSP中ACL访问控制表的配置和使用

一、拓扑图 1.新建拓扑图 2.PC端配置 PC1: PC2: PC3: 二、基本命令配置 1.S1配置 <Huawei>system-view [Huawei]sysname S1 [S1]vlan 10 [S1-vlan10]vlan 20 [S1-vlan20]vlan 30 [S1-vlan30]quit [S1]interface Vlanif 10 [S1-Vlanif10]ip address 192.168.10…

黑马点评06短信登录-用户请求和会话管理过程

用户请求发送&#xff1a; 用户的浏览器向服务器发送请求&#xff08;例如&#xff0c;访问网页或提交表单&#xff09;。请求头包含之前存储在浏览器中的Cookie&#xff0c;其中包括会话ID&#xff08;Session ID&#xff09;。 服务器接收请求&#xff1a; 服务器接收到用户的…

【PythonWeb开发】Flask自定义模板路径和静态资源路径

在大型的 Flask 项目中&#xff0c;确实可能会有多个子应用&#xff08;Blueprints&#xff09;&#xff0c;每个子应用可能都有自己的静态文件和模板。为了更好地管理和组织这些资源&#xff0c;可以使用static_folder 和template_folder 属性来统一管理。必须同时设置好主应用…

利用ChatGPT优化程序员工作流程:实用案例分享

近年来&#xff0c;人工智能技术的迅猛发展给各行各业带来了翻天覆地的变化。作为其中的一员&#xff0c;程序员在工作中也受益匪浅。其中&#xff0c;ChatGPT的出现&#xff0c;更是成为优化程序员工作流程的得力助手。本文将通过多个实用案例&#xff0c;分享如何利用ChatGPT…

鸿蒙系统最简单安装谷歌服务及软件的方法

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 近日&#xff0c;华为开发者大会在东莞松山湖召开&#xff0c;发布了盘古大模型5.0和纯血版的鸿蒙 HarmonyOS NEXT 全场景智能操作系统&#xff0c;而根据研究机构 Counterpoint Resea…

Unity关于Addressables.Release释放资源内存问题

前言 最近在编写基于Addressables的资源管理器&#xff0c;对于资源释放模块配合MemoryProfiler进行了测试&#xff0c;下面总结下测试Addressables.Release的结论。 总结 使用Addressables.Release释放资源时&#xff0c;通过MemoryProfiler检查内存信息发现加载的内容还在…

python-序列相关

序列&#xff08;squence&#xff09;是一组按顺序、紧密排列在一起的数据集。序列的作用是便于管理、方便数据操作更重要的是序列支持切片操作。 序列主要包括&#xff1a;列表、元组、字符串和字节串 内置数据结构&#xff1a; 容器&#xff1a;列表、元组、字典、集合 结构…

CVE-2020-26048(文件上传+SQL注入)

简介 CuppaCMS是一套内容管理系统&#xff08;CMS&#xff09;。 CuppaCMS 2019-11-12之前版本存在安全漏洞&#xff0c;攻击者可利用该漏洞在图像扩展内上传恶意文件&#xff0c;通过使用文件管理器提供的重命名函数的自定义请求&#xff0c;可以将图像扩展修改为PHP&#xf…

苹果笔记本双系统怎么安装

想要在mac电脑上装双系统&#xff0c;首先需要确认您的电脑是否支持。苹果电脑自带的boot camp工具可以帮助您在mac上安装windows系统&#xff0c;只需按照步骤进行操作即可。另外&#xff0c;您也可以使用虚拟机软件&#xff0c;如parallels desktop或vmware fusion&#xff0…