JavaWeb阶段学习知识点(二)

登录校验和JWT令牌实现

JWT使用方式

创建一个springboot项目,pom.xml引入jwt依赖

        <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><!-- 针对jdk17或者报错内容为:java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter 的小伙伴加一下下面的依赖 --><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency>

在测试类中,定义一个测试方法,测试jwt令牌生成

package com.jwz;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class test {/*** 生成jwt*/@Testvoid testSetJwt() {Map<String, Object> claims = new HashMap<>();claims.put("id",1);claims.put("name","xiaoji");/*** builder:用来构建jwt令牌* signWith: 生成jwt令牌使用的数字算法(jwt.io),官网有,参数一指定算法,参数二就是签名秘钥,这个随便写,但是切记不要少于5个字符,否则报错* setClaims:设置自定义数据(载荷)* setExpiration:设置令牌有效期,System.currentTimeMillis()+3600 当前时间+3600秒,也就是3600*1000毫秒后令牌过期,就是设置有效期为一小时* compact:调用compact可以拿到一个字符串类型的返回值*/String jinweizhe = Jwts.builder().signWith(SignatureAlgorithm.HS256, "jinweizhe").setClaims(claims).setExpiration(new Date(System.currentTimeMillis() + 3600*1000)).compact();System.out.println("生成的jwt为: "+jinweizhe); // 这个打印的就是jwt令牌// 生成的jwt为: eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoieGlhb2ppIiwiaWQiOjEsImV4cCI6MTcxNjIxODU2OH0.4-yMVfNWyb87TFryq8FJTiH_AAXLsmYGOFVybyjK15g}/*** 解析jwt*/@Testvoid testGetJwt(){/*** setSigningKey:指定签名秘钥* parseClaimsJws:传入jwt令牌* getBody:拿到自定义内容*/Claims jinweizhe = Jwts.parser().setSigningKey("jinweizhe").parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoieGlhb2ppIiwiaWQiOjEsImV4cCI6MTcxNjIxODU2OH0.4-yMVfNWyb87TFryq8FJTiH_AAXLsmYGOFVybyjK15g").getBody();System.out.println("解析到的jwt为: "+jinweizhe);  // 解析到的jwt为: {name=xiaoji, id=1, exp=1716218568}}
}
  • JWT校验时使用的签名秘钥,必须和生成IWT令牌时使用的秘钥是配套的
  • 如果JWT令牌解析校验时报错,则说明JWT令牌被篡改 或 失效了,令牌非法。

过滤器filter的使用操作

  • 定义Filter:定义一个类,实现 Filter 接口,并重写其所有方法。
  • 配置Filter:filter类上加 @WebFiter 注解,配置拦截资源的路径。引导类上加 @ServletComponentscan 开启Servlet组件支持,

登录校验流程

  • 获取请求url。
  • 判断请求url中是否包含login,如果包含,说明是登录操作,放行
  • 获取请求头中的令牌(token)
  • 判断令牌是否存在,如果不存在,返回错误结果(未登录)。
  • 解析token,如果解析失败,返回错误结果(未登录)
  • 放行。

在SpringBoot项目下,新建一个utils包和DemoFilter类

这里说明一下,下面用到的Result和JwtUtils都是工具包,下面有完整的项目代码,里面是有包含的,这里就不写出来了,可以往下翻找到完整项目代码

DemoFilter类内容如下

package com.jwz.login;import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;import java.io.IOException;
@Slf4j
@WebFilter(urlPatterns = "/*")  // 拦截所有的请求
// @WebFilter(urlPatterns = "/emps/*") // 访问emps下的所有资源的,都会被拦截
// @WebFilter(urlPatterns = "/login") // 拦截具体接口
public class DemoFilter implements Filter {// 还有init和destroy分别对应初始化方法和销毁方法,都只会调用一次,这两个不用重写,因为查看Filter源码会发现底层已经默认调用了,当然,想重写也可以// 这里只关注doFilter即可,他会在拦截到请求之后开始调用,会调用多次@Override // 拦截到请求之后调用,会调用多次,拦截到接口需要放行,否则接口不返回数据public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// System.out.println("拦截到请求了...放行之前的逻辑");// // 放行接口// // 参数1:请求对象  参数2:响应对象// // 放行后可以发现能正常返回数据了// filterChain.doFilter(servletRequest,servletResponse);// System.out.println("拦截到请求了...放行之后的逻辑");// 下面是登录校验的实现思路HttpServletRequest req = (HttpServletRequest) servletRequest;HttpServletResponse resp = (HttpServletResponse) servletResponse;// 将请求头和响应头都设置utf-8的格式,避免请求和响应结果有中文造成了乱码req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("UTF-8");resp.setContentType("application/json; charset=UTF-8");//1.获取请求ur1.String url = req.getRequestURL().toString();log.info("请求的url:{}",url);//2.判断请求url中是否包含login,如果包含,说明是获录操作,放行。if(url.contains("login")){log.info("登录操作,直接放行");filterChain.doFilter(servletRequest,servletResponse);return; // 停止代码继续向下执行}//3.获取请求头中的令牌(token)。String token = req.getHeader("token");//4.判断令牌是否存在、如果不存在,返回错误结果(未发录)if(!StringUtils.hasLength(token)){ // 判断字符串是否有长度log.info("请求头token为空,返回未登录信息");Result error = Result.error("未登录"); // 这里的Result是一个工具类,笔记下面的完整项目里面有工具文件代码// 手动转换 对象 -- json -----> 阿里巴巴fastJSON工具包(https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2/2.0.50)// 去上面地址复制代码到pom.xml依赖下载一下String noLogin = JSONObject.toJSONString(error); // 获取到json字符串(对象转成了json字符串)resp.getWriter().write(noLogin); // 将结果响应给浏览器return;}//5.解析token,如果解析失败,返回误结果(未录)// 这里的JwtUtils也是个工具类,跟上面的Result一样,下翻完整代码里面有工具类代码提供try {JwtUtils.parseJWT(token);} catch (Exception e) {// e.printStackTrace();log.info("令牌解析失败,返回未登录的错误信息");Result error = Result.error("未登录");String noLogin = JSONObject.toJSONString(error); // 获取到json字符串(对象转成了json字符串)resp.getWriter().write(noLogin); // 将结果响应给浏览器return;}//6.放行。log.info("令牌合法,直接放行");filterChain.doFilter(servletRequest, servletResponse);}
}

启动类新增一个注解

package com.jwz;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@ServletComponentScan // 开启了对servlet组件的支持
@SpringBootApplication
public class LoginVeifillyApplication {public static void main(String[] args) {SpringApplication.run(LoginVeifillyApplication.class, args);}}

测试用的controller

package com.jwz.login;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;
import java.util.Map;@Slf4j
@RestController
public class loginController {@PostMapping("/login")public Result login(@RequestBody loginEntity login){// 登陆成功,生成jwt并下发jwt返回给前端Map<String, Object> claims = new HashMap<>();claims.put("id",1);claims.put

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

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

相关文章

每月 GitHub 探索|10 款引领科技趋势的开源项目

1.IT-Tools 仓库名称&#xff1a; CorentinTh/it-tools 截止发稿星数: 16842 (近一个月新增:5744) 仓库语言: Vue 仓库开源协议&#xff1a; GNU General Public License v3.0 引言 CorentinTh/it-tools 是一个开源项目&#xff0c;提供各种对开发者友好的在线工具&#xff0…

48-4 内网渗透 - Rotten Potato(烂土豆) 提权

一、Potato家族提权 在渗透测试中,Potato家族是一种常用的提权技术,主要利用Windows服务账户的特权来将已获取的权限提升至系统(SYSTEM)级别。这种技术利用了两个关键的特权:SeAssignPrimaryTokenPrivilege和SeImpersonatePrivilege,这些特权允许用户在其他用户的安全上下…

【C语言】14.数组指针与函数指针及其应用

一、数组指针 顾名思义&#xff0c;数组指针就是指向数组的指针。形如&#xff1a;int (*p)[10]; 注意&#xff1a;[]的优先级要高于*号的&#xff0c;所以必须加上&#xff08;&#xff09;来保证p先和*结合。 数组指针的使用 int arr[10] {0}; int (*parr)[10] &arr;…

numpy-stl库的基本使用及notebook下的使用

numpy-stl库的基本使用及notebook下的可视化 https://pypi.org/project/numpy-stl/ 安装 conda install -c conda-forge numpy-stl引入资源 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits import mplot3d from stl import mesh读取stl文件 stl_fil…

springboot特殊问题处理2——springboot集成flowable实现工作流程的完整教程(一)

在实际项目开发过程中&#xff0c;流程相关的业务实现采用工作流会异常清晰明了&#xff0c;但是Activity学习成本和开发难度对追求效率的开发工作者来说异常繁琐&#xff0c;但是作为Activity的亲儿子之一的flowable&#xff0c;其轻量化的使用和对应的api会让开发者感受简单&…

超越GPT-4o!新王Claude 3.5 Sonnet来啦!免费使用

目录 01 比GPT-4o更智能&#xff0c;比Claude 3 Opus快两倍 02 最强视觉Model 03 使用Claude的新方式&#xff1a;Artifacts 04 安全性和透明度 Anthropic刚刚发布了全新大模型Claude 3.5 Sonnet&#xff0c;号称是迄今为止最智能的模型。一文几步教你注册使用Claude 3.5 S…

【面试题】风险评估和应急响应的工作流程

风险评估和应急响应是网络安全管理中两个重要的环节。下面分别介绍它们的工作流程&#xff1a; 一、风险评估工作流程&#xff1a; 1.确定评估范围&#xff1a;明确需要评估的信息系统或资产的范围。 2.资产识别&#xff1a;识别并列出所有需要评估的资产&#xff0c;包括硬件…

prometheus+grafana搭建监控系统

1.prometheus服务端安装 1.1下载包 使用wget下载 &#xff08;也可以直接去官网下载包Download | Prometheus&#xff09; wget https://github.com/prometheus/prometheus/releases/download/v2.44.0/prometheus-2.44.0.linux-amd64.tar.gz1.2解压 tar xf prometheus-2.44…

Modbus协议转Profibus协议网关模块连PLC与激光发射器通讯

一、概述 在PLC控制系统中&#xff0c;从站设备通常以Modbus协议&#xff0c;ModbusTCP协议&#xff0c;Profinet协议&#xff0c;Profibus协议&#xff0c;Profibus DP协议&#xff0c;EtherCAT协议&#xff0c;EtherNET协议等。本文将重点探讨PLC连接Modbus协议转Profibus协…

RGB彩色模型理解与编程实例

一、引言 RGB彩色模型中的R、G和B为三原色&#xff0c;通常R、G和B分别用8位表示&#xff0c;因此24位的RGB 真彩色图像能表示16777216种颜色。在如右图所示RGB彩色立方体可知&#xff0c;任意两种原色混合可以合成一种新的颜色。红&#xff08;1&#xff0c;0&#xff0c;0&a…

微型操作系统内核源码详解系列五(3):cm3下调度的开启

系列一&#xff1a;微型操作系统内核源码详解系列一&#xff1a;rtos内核源码概论篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列二&#xff1a;微型操作系统内核源码详解系列二&#xff1a;数据结构和对象篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列…

如何使用nginx部署https网站(亲测可行)

公司本来有网站sqlynx.com是http运行的&#xff0c;但因为产品出海&#xff0c;基本上都要求使用https&#xff0c;但又需要兼容已有的http服务&#xff0c;所以我自己尝试做了一次https的部署&#xff0c;目前是正常可用的。 目录 步骤 1&#xff1a;安装 Nginx 步骤 2&…

数据仓库的实际应用示例-广告投放平台为例

数据仓库的数据分层通常包括以下几层&#xff1a; ODS层&#xff1a;存放原始数据&#xff0c;如日志数据和结构化数据。DWD层&#xff1a;进行数据清洗、脱敏、维度退化和格式转换。DWS层&#xff1a;用于宽表聚合值和主题加工。ADS层&#xff1a;面向业务定制的应用数据层。…

node版本过高出现ERR_OSSL_EVP_UNSUPPORTED错误

错误原因&#xff1a; 新版本的nodejs使用的openssl和旧版本不同&#xff0c;导致出错 解决方法&#xff1a; 1.将node版本重新换回16.x 2 windows 下 在package.json文件下添加set NODE_OPTIONS--openssl-legacy-provider && "scripts": {"dev"…

Linux开发讲课8--- linux的5种IO模型

一、这里IO是什么 操作系统为了保护自己&#xff0c;设计了用户态、内核态两个状态。应用程序一般工作在用户态&#xff0c;当调用一些底层操作的时候&#xff08;比如 IO 操作&#xff09;&#xff0c;就需要切换到内核态才可以进行 服务器从网络接收的大致流程如下&#xff1…

非常难找的AI衣服图片处理工具推荐,一键轻松AI编辑

在当今数字化时代&#xff0c;AI技术已经渗透到我们生活的方方面面。特别是在图片处理领域&#xff0c;AI的强大功能让很多原本繁琐复杂的操作变得简单易行。今天&#xff0c;我要为大家推荐一款好用的AI衣服图片处理工具——让你一键轻松完成AI编辑&#xff0c;快速实现专业效…

wordpress站群搭建3api代码生成和swagger使用

海鸥技术下午茶-wordpress站群搭建3api代码生成和swagger使用 目标:实现api编写和swagger使用 0.本次需要使用到的脚手架命令 生成 http server 代码 goctl api go -api all.api -dir ..生成swagger文档 goctl api plugin -plugin goctl-swagger"swagger -filename st…

变电站智能巡检机器人解决方案

我国拥有庞大的电网体系&#xff0c;变电站数量众多&#xff0c;且近年来快速增长。然而目前我国变电站巡检方式仍以人工为主&#xff0c;存在效率低下、监控不全面等问题。变电站通常是一个封闭的系统空间&#xff0c;设备种类繁多、占地面积广阔&#xff0c;这对巡检人员实时…

缓存雪崩(主从复制、哨兵模式(脑裂)、分片集群)

缓存雪崩&#xff1a; 在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 方法一&#xff1a; 给不同key的TTL添加随机值&#xff0c;以此避免同一时间大量key失效。&#xff08;用于解决同一时间大量key过期&…

qt 如何获取磁盘信息、QStorageInfo

以往获取qt磁盘信息&#xff0c;笔者是通过一下API转换的 BOOL GetDiskFreeSpaceExW([in, optional] LPCWSTR lpDirectoryName,[out, optional] PULARGE_INTEGER lpFreeBytesAvailableToCaller,[out, optional] PULARGE_INTEGER lpTotalNumberOfBytes,[out, optional…