OA项目登录

news2025/1/13 14:54:14

导入依赖,下面的依赖是在这次OA登录中用到的

 <!--web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--Swagger2-->
        <!--Swagger-UI-->
        <!--访问路径:http://localhost:8080/swagger-ui.html-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

        <!--swaggerui  几个自定义界面方便查看接口-->
        <!--访问路径:http://localhost:8080/doc.html-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.6</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>25.1-jre</version>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!--JWT依赖-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
        <!-- 热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <!--google kaptcha验证码依赖-->
        <dependency>
            <groupId>com.github.axet</groupId>
            <artifactId>kaptcha</artifactId>
            <version>0.0.9</version>
        </dependency>
        <!--spring data redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

编写配置文件

server:
  port: 8081

spring:
  mvc:
    pathmatch:
      # \u89E3\u51B3spring2.6\u4EE5\u540E\u6574\u4E2Aswagger2\u7684\u95EE\u9898
      matching-strategy: ant_path_matcher
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/yeb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
    hikari:
      # \u8FDE\u63A5\u6C60\u540D
      pool-name: DataHikariCP
      # \u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5\u6570
      minimum-idle: 5
      # \u7A7A\u95F2\u8FDE\u63A5\u5B58\u6D3B\u6700\u5927\u65F6\u95F4\uFF0C\u9ED8\u8BA460000\uFF0810\u5206\u949F\uFF09
      idle-timeout: 180000
      # \u6700\u5927\u8FDE\u63A5\u6570\uFF0C\u9ED8\u8BA410
      maximum-pool-size: 10
      # \u4ECE\u8FDE\u63A5\u6C60\u8FD4\u56DE\u7684\u8FDE\u63A5\u7684\u81EA\u52A8\u63D0\u4EA4
      auto-commit: true
      # \u8FDE\u63A5\u6700\u5927\u5B58\u6D3B\u65F6\u95F4\uFF0C0\u8868\u793A\u6C38\u4E45\u5B58\u6D3B\uFF0C\u9ED8\u8BA41800000\uFF0830\u5206\u949F\uFF09
      max-lifetime: 1800000
      # \u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4\uFF0C\u9ED8\u8BA430000\uFF0830\u79D2\uFF09
      connection-timeout: 30000
      # \u6D4B\u8BD5\u8FDE\u63A5\u662F\u5426\u53EF\u7528\u7684\u67E5\u8BE2\u8BED\u53E5
      connection-init-sql: SELECT 1

  redis:
    # \u8D85\u65F6\u65F6\u95F4
    timeout: 10000ms
    # \u670D\u52A1\u5668\u5730\u5740
    host: 127.0.0.1
    # \u670D\u52A1\u5668\u7AEF\u53E3
    port: 6379
    database: 0
    lettuce:
      pool:
        # \u8FDE\u63A5\u6C60\u6700\u5927\u8FDE\u63A5\u6570 \u9ED8\u8BA48 \uFF0C\u8D1F\u6570\u8868\u793A\u6CA1\u6709\u9650\u5236
        max-active: 1024
        # \u6700\u5927\u8FDE\u63A5\u963B\u585E\u7B49\u5F85\u65F6\u95F4\uFF0C\u9ED8\u8BA4-1
        max-wait: 10000ms
        # \u6700\u5927\u7A7A\u95F2\u8FDE\u63A5
        max-idle: 200
        # \u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5
        min-idle: 5
    password:

mybatis-plus:
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  type-aliases-package: com.atguigu.oaserver.pojo
  configuration:
    # \u5173\u95ED\u81EA\u52A8\u9A7C\u5CF0\u547D\u540D
    map-underscore-to-camel-case: false

# mybatis SQL \u6253\u5370
logging:
  level:
    com.atguigu.oaserver.mapper: debug

jwt:
  # JWT存储的请求头
  tokenHeader: Authorization
  # JWT加密使用的密钥
  secret: yeb-secret
  # JWT的超期限时间(60*60*24) 即24小时失效
  expiration: 604800000
  # JWT载荷中拿到开头 不要改
  tokenHead: Bearer

之后再用代码生成器生成所需要的类,接口

在controller定义登录方法

加载用户信息,判断密码,账号转态

因为要判断加密密码所以要用到passwordEncoder

loadUserByUsername通过实现userDetailsService来的

在TAdminUserDetailsServiceImpl里面判断用户是否存在

getAdminByUserName就是一个单查,根据username去查询用户是否存在

@Override
public TAdmin getAdminByUserName(String username) {
    QueryWrapper<TAdmin> qw = new QueryWrapper();
    qw.eq("username", username);
    TAdmin one = this.getOne(qw);
    return one;
}

账号状态和密码都没有问题之后生成token

RespBean工具类,用来响应结果封装类,用于统一返回给前端的数据格式

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RespBean {
    // 响应状态码
    private long code;
    // 响应消息
    private String msg;
    // 响应数据
    private Object data;

    /**
     * 创建一个成功的响应结果,不包含数据
     *
     * @param message 响应消息
     * @return 成功的响应结果
     */
    public static RespBean success(String message) {
        return new RespBean(200, message, null);
    }

    /**
     * 创建一个成功的响应结果,包含数据
     *
     * @param message 响应消息
     * @param obj 响应数据
     * @return 成功的响应结果
     */
    public static RespBean success(String message, Object obj) {
        return new RespBean(200, message, obj);
    }

    /**
     * 创建一个失败的响应结果,不包含数据
     *
     * @param message 响应消息
     * @return 失败的响应结果
     */
    public static RespBean error(String message) {
        return new RespBean(500, message, null);
    }

    /**
     * 创建一个失败的响应结果,包含数据
     *
     * @param message 响应消息
     * @param obj 响应数据
     * @return 失败的响应结果
     */
    public static RespBean error(String message, Object obj) {
        return new RespBean(500, message, obj);
    }
}

JwtUtils工具类

@Data
@Component
public class JwtUtils {
    @Value("${jwt.tokenHead}")
    String tokenHead;
    @Value("${jwt.secret}")
    String secret;
    @Value("${jwt.expiration}")
    int expiration;
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    public String genenerateToken(String username) {
        Date exDate = new Date(System.currentTimeMillis() + expiration);
        return Jwts.builder()
                .setSubject(username)// 主题
                .setIssuedAt(new Date())// 签发时间
                .setExpiration(exDate)// 过期时间
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }
}

上面的@value来之配置文件yml,tokenHeader的值一定不要更改

jwt:
  # JWT存储的请求头
  tokenHeader: Authorization
  # JWT加密使用的密钥
  secret: yeb-secret
  # JWT的超期限时间(60*60*24) 即24小时失效
  expiration: 604800000
  # JWT载荷中拿到开头 不要改
  tokenHead: Bearer

这边既然需要登录那必然要编写security用来登录

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 允许访问/login
        http.authorizeRequests()
                .mvcMatchers("/login").permitAll()
                .anyRequest().permitAll();
        // 关闭csrf
        http.csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        // 禁用缓存
        http.headers()
                .cacheControl();
}

之后根据自己配置的端口号和数据库中的数据进行登录测试

比如我的就是:localhost:8081/login?username=admin&password=123456

如果浏览器装配了JSON插件,然后不出意外的话就可以在浏览器看到这样子的

后面就是获取token里面的数据,你登录之后把登录的用户的数据存入token,那如何获取它呢

先来编写一个这样子方法

  /**
     * 获取管理员信息
     *
     * @param token 用户名和密码认证令牌,用于获取当前登录的管理员信息
     * @return RespBean 包含管理员信息的响应对象
     */
    @RequestMapping("/admin/info")
    public RespBean getAminInfo(UsernamePasswordAuthenticationToken token) {
        // 从认证令牌中获取管理员对象
        TAdmin principal = (TAdmin) token.getPrincipal();
        // 打印管理员信息,用于调试和日志记录
        System.out.println(principal);
        // 返回成功响应,包含管理员信息
        return RespBean.success("获取用户信息成功", principal);
    }

你想要获取登录人员的信息,那就要有个JWT认证过滤器


/**
 * JWT认证过滤器,用于拦截请求并验证JWT令牌
 */
public class JwtAuthencationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private TAdminUserDetailsServiceImpl userDetailsService;

    /**
     * 执行过滤器的主要方法
     *
     * @param request   HttpServletRequest对象,用于获取请求信息
     * @param response  HttpServletResponse对象,用于设置响应信息
     * @param filterChain 过滤链,用于将请求传递给下一个过滤器或目标资源
     * @throws ServletException 如果过滤过程中发生Servlet异常
     * @throws IOException 如果过滤过程中发生IO异常
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 从请求头中获取JWT令牌
        String token = request.getHeader(jwtUtils.getTokenHeader());
        // 打印令牌信息,用于调试
        System.out.println("token=======>" + token);
        if (token != null && token.startsWith(jwtUtils.getTokenHead())) {
            // 移除令牌前缀,获取纯令牌字符串
            String[] s = token.split(" ");
            token = s[1];
            System.out.println("token=======>" + token);
            // 从令牌中提取用户名
            String username = jwtUtils.getUserNameFromTokens(token);
            System.out.println("username=======>" + username);
            // 如果用户名不为空且上下文中尚未进行认证
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                // 根据用户名获取用户详细信息
                TAdmin tAdmin = (TAdmin) userDetailsService.loadUserByUsername(username);
                // 设置认证信息
                UsernamePasswordAuthenticationToken authenticationToken =
                        new UsernamePasswordAuthenticationToken(tAdmin, null, tAdmin.getAuthorities());
                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        // 将请求传递给过滤链中的下一个元素
        filterChain.doFilter(request, response);
    }
}

然后这个过滤器放到security里面进行添加

之后就可以用ApiFox这个软件来进行测试

先打开apifox,就是下面图中的软件

然后跟着下面的步骤来

这里的信息来着登录成功之后的tokenHead和token,tokenHead后面记得打空格

这样就可以看到登录的用户信息了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电池预测 | 第21讲 基于Gamma伽马模型结合EM算法和粒子滤波算法参数估计的锂电池剩余寿命预测

电池预测 | 第21讲 基于Gamma伽马模型结合EM算法和粒子滤波算法参数估计的锂电池剩余寿命预测 目录 电池预测 | 第21讲 基于Gamma伽马模型结合EM算法和粒子滤波算法参数估计的锂电池剩余寿命预测预测效果基本描述程序设计参考资料 预测效果 基本描述 电池预测 | 第21讲 基于Ga…

实用操作系统学习笔记

第1章 操作系统概述 操作系统基本概念 【基础知识】 操作系统&#xff1a;控制和管理整个计算机系统的硬件和软件资源&#xff0c;合理地组织、调度计算机的工作与资源的分配&#xff0c;进而为用户和其他软件提供方便接口与环境的程序集合。操作系统是计算机系统中最基本的…

银河麒麟桌面操作系统搭建FTP服务器

一、操作环境 服务端&#xff1a;银河麒麟桌面操作系统V10 客户端&#xff1a;银河麒麟桌面操作系统V10 二、服务器配置 说明&#xff1a;以下命令均在终端执行。鼠标点击桌面右键&#xff0c;在终端中打开。 操作步骤&#xff1a; &#xff08;一&#xff09;安装vsftpd…

20250112面试鸭特训营第20天

更多特训营笔记详见个人主页【面试鸭特训营】专栏 250112 1. TCP 和 UDP 有什么区别&#xff1f; 特性TCPUDP连接方式面向连接&#xff08;需要建立连接&#xff09;无连接&#xff08;无需建立连接&#xff09;可靠性可靠的&#xff0c;提供确认、重传机制不可靠&#xff0c…

深入理解 C 语言中浮点型数据在内存中的存储

文章目录 一、浮点型数据存储格式&#xff08;IEEE 754 标准&#xff09;二、举例说明单精度浮点数存储过程三、绘图说明四、双精度浮点数存储示例&#xff08;以1.5为例&#xff09; 在 C 语言的世界里&#xff0c;数据类型丰富多样&#xff0c;而浮点型数据用于表示实数&…

使用uniapp 微信小程序一些好用的插件分享

总结一下自己在开发中遇见的一问题&#xff0c;通过引入组件可以快速的解决 1.zxz-uni-data-select 下拉框选择器(添加下拉框检索&#xff0c;多选功能&#xff0c;多选搜索功能&#xff0c;自定义 下拉框插件&#xff0c;使用这个的原因是因为 uniui uview 组件库下拉框太…

kafka消费堆积问题探索

背景 我们的商城项目用PHP写的&#xff0c;原本写日志方案用的是PHP的方案&#xff0c;但是&#xff0c;这个方案导致资源消耗一直降不下来&#xff0c;使用了20个CPU。后面考虑使用通过kafka的方案写日志&#xff0c;商城中把产生的日志丢到kafka中&#xff0c;在以go写的项目…

使用conda出现requests.exceptions.HTTPError 解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

智能化文档开发(DI)

这个文档涉及到多模态&#xff08;文本、发票、订单、语音&#xff09; 对于普通的文本&#xff0c;我们希望对某些实体的某些属性挖空生成文档模版&#xff0c;并根据预设字段填空最后生成正式文件对于发票、订单&#xff0c;我们想提取它的字段信息&#xff0c;写入DB对于一些…

RAID储存技术

RAID独立磁盘冗余技术是一种把2个或者多个HDD或SSD合并为一个协调的存储单元或列阵&#xff0c;从而预防数据丢失的技术&#xff0c;其最早由加州大学伯克利分校的计算机科学家David Patterson、Garth Gibson和Randy Katz在1987年提出。他们的研究论文“关于RAID的论证”提出了…

Java Web开发基础:HTML的深度解析与应用

文章目录 前言&#x1f30d;一.B/S 软件开发架构简述&#x1f30d;二.HTML 介绍❄️2.1 官方文档❄️2.2 网页的组成❄️2.3 HTML 是什么❄️2.4html基本结构 &#x1f30d;三.HTML标签1.html 的标签/元素-说明2. html 标签注意事项和细节3.font 字体标签4.标题标签5.超链接标签…

使用 WPF 和 C# 绘制图形

绘图困难 此示例展示了如何在 WPF 和 C# 中绘制图形。绘制图形总是很棘手&#xff0c;因为您通常需要在至少两个不同的坐标系中工作。首先&#xff0c;您要为图形使用世界坐标。例如&#xff0c;您可能希望 X 值的范围为 2000 年至 2020 年&#xff0c;Y 值的范围为 10,000 美元…

年度技术突破奖|中兴微电子引领汽车芯片新变革

随着以中央计算区域控制为代表的新一代整车电子架构逐步成为行业主流&#xff0c;车企在电动化与智能化之后&#xff0c;正迎来以架构创新为核心的新一轮技术竞争。中央计算SoC&#xff0c;作为支撑智驾和智舱高算力需求的核心组件&#xff0c;已成为汽车电子市场的重要新增量。…

【JVM-2.3】深入解析JVisualVM:Java性能监控与调优利器

在Java应用的开发和运维过程中&#xff0c;性能监控与调优是不可或缺的环节。无论是排查内存泄漏、分析CPU瓶颈&#xff0c;还是优化线程使用&#xff0c;开发者都需要借助一些强大的工具来辅助诊断。JVisualVM 正是这样一款由Oracle提供的免费工具&#xff0c;它集成了多种性能…

filestream安装使用全套+filebeat的模块用法

1 filestream介绍 官方宣布&#xff1a;输入类型为log在filebeat7.16版本已经弃用了 Filestream 是 Filebeat 中的一种 输入类型&#xff08;Input&#xff09;&#xff0c;用于处理日志文件的读取。它是为了取代 Filebeat 中传统的 log 输入&#xff08;Input&#xff09;设…

超燃预告!Origin百图绘制系列即将登场

Hello&#xff0c;大家好 这里是练习时长两年半的菜狗~ 持续更新各种竞赛&#xff0c;科研&#xff0c;保研&#xff0c;学习干货ing 回想刚开始打比赛那会&#xff0c;啥都不懂&#xff0c;就从用 Excel 画图起步&#xff0c;绘制的图形实在太难看。后来运用 Matlab&#xf…

八、系统托盘与配置面板

没有人会把你变得越来越好&#xff0c;时间和经历只是陪衬。 支撑你变得越来越好的&#xff0c;是你自己坚强的意志、修养、品行、以及不断的反思和经验。 人生最好的贵人&#xff0c;就是努力向上的自己。 一、系统托盘 1、资源文件夹 新建资源文件夹&#xff0c;我们需要把…

uniapp 之 uni-forms校验提示【提交的字段[‘xxx‘]在数据库中并不存在】解决方案

目录 场景问题代码结果问题剖析解决方案 场景 uni-forms官方组件地址 使用uniapp官方提供的组件&#xff0c;某个表单需求&#xff0c;单位性质字段如果是高校&#xff0c;那么工作单位则是高校的下拉选择格式&#xff0c;单位性质如果是其他的类型&#xff0c;工作单位则是手动…

Java面试核心知识4

公平锁与非公平锁 公平锁&#xff08;Fair&#xff09; 加锁前检查是否有排队等待的线程&#xff0c;优先排队等待的线程&#xff0c;先来先得 非公平锁&#xff08;Nonfair&#xff09; 加锁时不考虑排队等待问题&#xff0c;直接尝试获取锁&#xff0c;获取不到自动到队尾…

基于 SSH 的任务调度系统

文末附有完整项目代码 在当今科技飞速发展的时代&#xff0c;任务调度系统的重要性日益凸显。本文将详细介绍一个基于 SSH&#xff08;SpringStruts2Hibernate&#xff09;的任务调度系统的设计与实现。 一、系统概述 本系统旨在改变传统人工任务调度方式&#xff0c;通过计算…