OA项目登录
导入依赖,下面的依赖是在这次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: 8081spring:mvc:pathmatch:# \u89E3\u51B3spring2.6\u4EE5\u540E\u6574\u4E2Aswagger2\u7684\u95EE\u9898matching-strategy: ant_path_matcherdatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/yeb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: rootpassword: roothikari:# \u8FDE\u63A5\u6C60\u540Dpool-name: DataHikariCP# \u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5\u6570minimum-idle: 5# \u7A7A\u95F2\u8FDE\u63A5\u5B58\u6D3B\u6700\u5927\u65F6\u95F4\uFF0C\u9ED8\u8BA460000\uFF0810\u5206\u949F\uFF09idle-timeout: 180000# \u6700\u5927\u8FDE\u63A5\u6570\uFF0C\u9ED8\u8BA410maximum-pool-size: 10# \u4ECE\u8FDE\u63A5\u6C60\u8FD4\u56DE\u7684\u8FDE\u63A5\u7684\u81EA\u52A8\u63D0\u4EA4auto-commit: true# \u8FDE\u63A5\u6700\u5927\u5B58\u6D3B\u65F6\u95F4\uFF0C0\u8868\u793A\u6C38\u4E45\u5B58\u6D3B\uFF0C\u9ED8\u8BA41800000\uFF0830\u5206\u949F\uFF09max-lifetime: 1800000# \u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4\uFF0C\u9ED8\u8BA430000\uFF0830\u79D2\uFF09connection-timeout: 30000# \u6D4B\u8BD5\u8FDE\u63A5\u662F\u5426\u53EF\u7528\u7684\u67E5\u8BE2\u8BED\u53E5connection-init-sql: SELECT 1redis:# \u8D85\u65F6\u65F6\u95F4timeout: 10000ms# \u670D\u52A1\u5668\u5730\u5740host: 127.0.0.1# \u670D\u52A1\u5668\u7AEF\u53E3port: 6379database: 0lettuce:pool:# \u8FDE\u63A5\u6C60\u6700\u5927\u8FDE\u63A5\u6570 \u9ED8\u8BA48 \uFF0C\u8D1F\u6570\u8868\u793A\u6CA1\u6709\u9650\u5236max-active: 1024# \u6700\u5927\u8FDE\u63A5\u963B\u585E\u7B49\u5F85\u65F6\u95F4\uFF0C\u9ED8\u8BA4-1max-wait: 10000ms# \u6700\u5927\u7A7A\u95F2\u8FDE\u63A5max-idle: 200# \u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5min-idle: 5password:mybatis-plus:mapper-locations: classpath*:mapper/**/*Mapper.xmltype-aliases-package: com.atguigu.oaserver.pojoconfiguration:# \u5173\u95ED\u81EA\u52A8\u9A7C\u5CF0\u547D\u540Dmap-underscore-to-camel-case: false# mybatis SQL \u6253\u5370
logging:level:com.atguigu.oaserver.mapper: debugjwt:# 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 {@Overrideprotected void configure(HttpSecurity http) throws Exception {// 允许访问/loginhttp.authorizeRequests().mvcMatchers("/login").permitAll().anyRequest().permitAll();// 关闭csrfhttp.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 {@Autowiredprivate JwtUtils jwtUtils;@Autowiredprivate TAdminUserDetailsServiceImpl userDetailsService;/*** 执行过滤器的主要方法** @param request HttpServletRequest对象,用于获取请求信息* @param response HttpServletResponse对象,用于设置响应信息* @param filterChain 过滤链,用于将请求传递给下一个过滤器或目标资源* @throws ServletException 如果过滤过程中发生Servlet异常* @throws IOException 如果过滤过程中发生IO异常*/@Overrideprotected 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后面记得打空格


这样就可以看到登录的用户信息了
相关文章:
OA项目登录
导入依赖,下面的依赖是在这次OA登录中用到的 <!--web依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.sprin…...
verilogHDL仿真详解
前言 Verilog HDL中提供了丰富的系统任务和系统函数,用于对仿真环境、文件操作、时间控制等进行操作。(后续会进行补充) 正文 一、verilogHDL仿真详解 timescale 1ns/1ps //时间单位为1ns,精度为1ps, //编译…...
基于http协议的天气爬虫
该系统将基于目前比较流行的网络爬虫技术, 对网站上的天气数据进行查询分析, 最终使客户能够通过简单的操作, 快速, 准确的获取目标天气数据。主要包括两部分的功能, 第一部分是天气数据查询, 包括时间段数…...
_STM32关于CPU超频的参考_HAL
MCU: STM32F407VET6 官方最高稳定频率:168MHz 工具:STM32CubeMX 本篇仅仅只是提供超频(默认指的是主频)的简单方法,并未涉及STM32超频极限等问题。原理很简单,通过设置锁相环的倍频系数达到不同的频率&am…...
C#,图论与图算法,任意一对节点之间最短距离的弗洛伊德·沃肖尔(Floyd Warshall)算法与源程序
一、弗洛伊德沃肖尔算法 Floyd-Warshall算法是图的最短路径算法。与Bellman-Ford算法或Dijkstra算法一样,它计算图中的最短路径。然而,Bellman Ford和Dijkstra都是单源最短路径算法。这意味着他们只计算来自单个源的最短路径。另一方面,Floy…...
AWS云计算概览(自用留存,整理中)
目录 一、云概念概览 (1)云计算简介 (2)云计算6大优势 (3)web服务 (4)AWS云采用框架(AWS CAF) 二、云经济学 & 账单 (1)定…...
1. npm 常用命令详解
npm 常用命令详解 npm(Node Package Manager)是 Node.js 的包管理工具,用于安装和管理 Node.js 应用中的依赖库。下面是 npm 的一些常用命令及其详细解释和示例代码。 镜像源 # 查询当前使用的镜像源 npm get registry# 设置为淘宝镜像源 …...
js:根据后端返回数据的最大值进行计算然后设置这个最大值为百分之百,其他的值除这个最大值
问: 现在tabData.value 接收到了后端返回的数据, [{text:人力,percentage:‘90’},{text:物品,percentage:‘20’},{text:物理,percentage:‘50’},{text:服务,percentageÿ…...
【Spring】@Size 无法拦截null的原因
问题复现 在构建 Web 服务时,我们一般都会对一个 HTTP 请求的 Body 内容进行校验,例如我们来看这样一个案例及对应代码。当开发一个学籍管理系统时,我们会提供了一个 API 接口去添加学生的相关信息,其对象定义参考下面的代码&…...
【Block总结】掩码窗口自注意力 (M-WSA)
摘要 论文链接:https://arxiv.org/pdf/2404.07846 论文标题:Transformer-Based Blind-Spot Network for Self-Supervised Image Denoising Masked Window-Based Self-Attention (M-WSA) 是一种新颖的自注意力机制,旨在解决传统自注意力方法在…...
用 HTML5 Canvas 和 JavaScript 实现雪花飘落特效
这篇文章将带您深入解析使用 HTML5 Canvas 和 JavaScript 实现动态雪花特效的代码原理。 1,效果展示 该效果模拟了雪花从天而降的动态场景,具有以下特点: 雪花数量、大小、透明度和下落速度随机。雪花会在屏幕底部重置到顶部,形成循环效果。随窗口大小动态调整,始终覆盖…...
【cocos creator】【ts】事件派发系统
触发使用: EventTool.emit(“onClick”) 需要监听的地方,onload调用: EventTool.on(“onClick”, this.onClickEvent, this) /**事件派发*/class EventTool {protected static _instance: EventTool null;public static get Instance(): Eve…...
《探索鸿蒙Next上开发人工智能游戏应用的技术难点》
在科技飞速发展的当下,鸿蒙Next系统为应用开发带来了新的机遇与挑战,开发一款运行在鸿蒙Next上的人工智能游戏应用更是备受关注。以下是在开发过程中可能会遇到的一些技术难点: 鸿蒙Next系统适配性 多设备协同:鸿蒙Next的一大特色…...
CSS | CSS实现两栏布局(左边定宽 右边自适应,左右成比自适应)
目录 一、左边定宽 右边自适应 1.浮动 2.利用浮动margin 3.定位margin 4.flex布局 5.table 布局 二、左右成比自适应 1:1 1flex布局 table布局 1:2 flex布局 <div class"father"><div class"left">左边自适应</div><div class"r…...
acwing_3195_有趣的数
acwing_3195_有趣的数 // // Created by HUAWEI on 2024/11/17. // #include<iostream> #include<cstring> #include<algorithm>#define int long longusing namespace std;const int N 1000 50; const int MOD 1e9 7; int C[N][N]; //组合数signed mai…...
Liunx-搭建安装VSOMEIP环境教程 执行 运行VSOMEIP示例demo
本文安装环境为Liunx,搭建安装VSOMEIP环境并运行基础例子。 1. 安装基础环境 使用apt-get来安装基础环境,受网络影响可以分开多次安装。环境好的也可以一次性执行。 sudo apt-get install gcc g sudo apt-get install cmake sudo apt-get install lib…...
Git | git revert命令详解
关注:CodingTechWork 引言 Git 是一个强大的版本控制工具,广泛应用于现代软件开发中。它为开发人员提供了多种功能来管理代码、协作开发和版本控制。在 Git 中,有时我们需要撤销或回退某些提交,而git revert 是一个非常有用的命令…...
ASP.NET Core 中,Cookie 认证在集群环境下的应用
在 ASP.NET Core 中,Cookie 认证在集群环境下的应用通常会遇到一些挑战。主要的问题是 Cookie 存储在客户端的浏览器中,而认证信息(比如 Session 或身份令牌)通常是保存在 Cookie 中,多个应用实例需要共享这些 Cookie …...
Flyte工作流平台调研(五)——扩展集成
系列文章: Flyte工作流平台调研(一)——整体架构 Flyte工作流平台调研(二)——核心概念说明 Flyte工作流平台调研(三)——核心组件原理 Flyte工作流平台调研(四)——…...
【AUTOSAR 基础软件】软件组件的建立与使用(“代理”SWC)
基础软件往往需要建立一些“代理”SWC来完成一些驱动的抽象工作(Complex_Device_Driver_Sw或者Ecu_Abstraction_Sw等),或建立Application Sw Component来补齐基础软件需要提供的功能实现。当面对具体的项目时,基础软件开发人员还可…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
