18.JavaWeb-JWT(登录、鉴权)

1.CSRF跨站请求伪造

        跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

        为了防止CSRF攻击,产检的防御措施有:生成随即令牌(token)、设置Cookie的SameSite属性为Strict或Lax 、验证Referer字段、双重身份验证等

2.JWT概念

        JWT(JSON Web Token)是一种用于进行身份验证和授权的开放标准(RFC 7519)。它是一种安全的、基于JSON的令牌,用于在客户端和服务器之间传递声明

 2.1 JWT组成

header声明类型、声明加密的算法,通常直接使用HMAC SHA256或RSA
payload也称为JWT Claims,包含用户的一些非隐私数据(秘钥、签发人、签发时间、有效时间等)
Signature签证信息,由三部分组成:header(base64后的)、payload(base64后的)、secred

3.登录详细流程

3.1 单token验证

3.1.1 登录成功,生成token并返回

        1.生成token

String token = JWTUtil.generateToken(user.getId());

        2.设置响应头

response.setHeader("authorization", token);

        3.暴露响应头

        浏览器不认识自定义的头,如果不暴露浏览器会自动屏蔽

response.setHeader("Access-Control-Expose-Headers","authorization");

3.1.2 前端得到token保存在浏览器本地

        sessionstorage:在会话期间有效(浏览器打开期间)
        localstorage:只要不主动删除、不卸载浏览器,数据一直有效

let token = res.headers.authorization
window.localStorage.setItem("authorization", token)

3.1.3 通过axios拦截器自动携带token

http.interceptors.request.use(config =>{// 得到token  本地let token = window.localStorage.getItem("authorization")config.headers.authorization = token// 放行请求return config}
)

3.1.4 自定义过滤器验证token

if (token == null || token.length() == 0 || token.equals("null")){// 没登录extracted(servletResponse);// 终止return;
}else {// 有tokenif (JWTUtil.verify(token) == TokenEnum.TOKEN_SUCCESS){// 合法,放行request.getSession().setAttribute("uid", JWTUtil.getuid(token));filterChain.doFilter(servletRequest, servletResponse);}else {// 伪造或者过期,都让登录extracted(servletResponse);// 终止请求return;}
}private static void extracted(ServletResponse servletResponse) throws IOException {ResponseResult<Object> responseResult = new ResponseResult<>(403,"无法访问此界面,请登录",null);//转jsonString json = new ObjectMapper().writeValueAsString(responseResult);//设置响应头servletResponse.setContentType("application/json;charset=utf-8");servletResponse.getWriter().write(json);
}

3.2 双token验证(安全性更高)

3.2.1 登录成功生成两个token

//生成Token令牌
String token = JWTUtil.generateToken(user.getId());
//生成refreshToken
String refreshtoken = UUID.randomUUID().toString();

3.2.2 以refreshtoken作为key,token作为value放入Redis并设置过期时间

redisTemplate.opsForValue().set(refreshtoken,token,JWTUtil.REFRESH_TOKEN_EXPIRE_TIME, TimeUnit.MILLISECONDS);

3.2.3 设置响应头、暴露头

//将token放到响应头中返回给前端(流行做法)
response.setHeader("authorization",token);
response.setHeader("refreshtoken",refreshtoken);
//暴露头,浏览器不认识自定义的头,如果不暴露浏览器会自动屏蔽
response.setHeader("Access-Control-Expose-Headers","authorization,refreshtoken");

3.2.4 前端在响应拦截器上得到两个token放到本地

http.interceptors.response.use(response =>{// 判断响应中是否有token信息,如果有则将token放到本地let token = response.headers.authorizationif(token){// 不为空放本地window.localStorage.setItem("authorization", token)}let refreshtoken = response.headers.refreshtokenconsole.log(refreshtoken)if(refreshtoken){window.localStorage.setItem("refreshtoken", refreshtoken)}return response}
)

3.2.5 前端在请求拦截将两个token设置到请求头

http.interceptors.request.use(config =>{// 从浏览器本地得到tokenlet token = window.localStorage.getItem("authorization")let refreshtoken = window.localStorage.getItem("refreshtoken")config.headers.authorization = tokenconfig.headers.refreshtoken = refreshtoken// 放行请求return config}
)

3.2.6 在AuthFilter校验两个token

//需要登录
//获取token
String token = request.getHeader("authorization");
String refreshtoken = request.getHeader("refreshtoken");//校验refreshtoken是否过期
if(refreshtoken==null || refreshtoken.length()==0 || refreshtoken.equals("null")||!redisTemplate.hasKey(refreshtoken)){//非法、过期   去登陆extracted(servletResponse);return;
}
//判断token
if(token==null || token.length()==0 || token.equals("null")){//没登陆extracted(servletResponse);return;
}else{if(JWTUtil.verify(token) == TokenEnum.TOKEN_SUCCESS){//进一步的安全验证if(token.equals(redisTemplate.opsForValue().get(refreshtoken))){//合法,登录成功//过滤器放行:让后面的过滤器 或者 servlet处理这个请求
//                    request.getSession().setAttribute("uid",JWTUtil.getuid("authorization"));filterChain.doFilter(servletRequest, servletResponse);}else{//伪造extracted(servletResponse);return;}}else if(JWTUtil.verify(token) == TokenEnum.TOKEN_EXPIRE){//过期 重新生成tokentoken = JWTUtil.generateToken(JWTUtil.getuid(token));//判断token与后台记录的是否一致//进一步的安全验证if(token.equals(redisTemplate.opsForValue().get(refreshtoken))){//修改redis的数据redisTemplate.opsForValue().set(refreshtoken,token,JWTUtil.REFRESH_TOKEN_EXPIRE_TIME, TimeUnit.MILLISECONDS);//将新的token返回前端//将token放到响应头中返回给前端(流行做法)HttpServletResponse response = (HttpServletResponse) servletResponse;response.setHeader("authorization",token);response.setHeader("refreshtoken",refreshtoken);//暴露头,浏览器不认识自定义的头,如果不暴露浏览器会自动屏蔽response.setHeader("Access-Control-Expose-Headers","authorization");filterChain.doFilter(servletRequest, servletResponse);}else{//伪造extracted(servletResponse);return;}}else{//伪造extracted(servletResponse);return;}

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

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

相关文章

postman测试传参格式

postman测试传参格式 创建User实体 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data NoArgsConstructor AllArgsConstructor public class User {private Integer id;private String name; }接口参数是集合 PostMapping("…

第50步 深度学习图像识别:Data-efficient Image Transformers建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;Data-efficient Image Transformers Data-efficient Image Transformers (DeiT)是一种用于图像分类的新型模型&#xff0c;由Facebook AI在2020年底提出。这种方法基于视觉Transformer&#xff0c;通过训练策…

LoRA指令微调——源码解析

目录 1. lit-llama工程2. LoRA部分3. 代码部分4. LoRA模型文件 &#xff08;本次博文的LoRA代码主要基于lit-llama工程&#xff09; 1. lit-llama工程 lit-llama是一个大语言模型的工程&#xff0c;可用于语言模型的训练、测试等优点&#xff1a;很简洁&#xff0c;代码也很容…

健身房综合云管理项目

博主简介&#xff1a; 河南沐斯特网络科技有限公司技术顾问&#xff1b; 天津集创科技有限公司创始人之一兼前端开发工程师/python开发&#xff1b; 第十四届中国服务外包大赛华北地区(九个省加自治区直辖市)三等奖&#xff1b; CSDN官方内容合伙人&#xff0c; CSDN.2023年…

C++_简单模拟实现string的增删查改

目录 一、模拟reserve 二、模拟push_back 三、模拟append 四、模拟operator 五、模拟insert 六、模拟erase 七、模拟find 八、模拟substr 一、模拟reserve 要添加数据&#xff0c;首先要考虑的是扩容。有必要用reserve辅助扩容。reserve的作用就是给一个预期的值作为扩…

2023金九银十大厂 Java 面试八股文大全(整理版)附答案详解

Java 面试八股文有必要背吗&#xff1f; 我的回答是&#xff1a;很有必要。你可以讨厌这种模式&#xff0c;但你一定要去背&#xff0c;因为不背你就进不了大厂。现如今&#xff0c;Java 面试的本质就是八股文&#xff0c;把八股文面试题背好&#xff0c;面试才有可能表现好。…

STM32 Proteus仿真空气质量检测环境监测苯PM2.5 MQ135温度湿度 -0068

STM32 Proteus仿真空气质量检测环境监测苯PM2.5 MQ135温度湿度 -0068 Proteus仿真小实验&#xff1a; STM32 Proteus仿真空气质量检测环境监测苯PM2.5 MQ135温度湿度 -0068 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 LCD1602显示器DHT11温度湿度多个按键蜂鸣…

Visual Studio 2017下的C++开发环境搭建

Visual Studio 是Microsoft旗下的开发工具包系列产品&#xff0c;是一个基本完整的开发工具集&#xff0c;它包括整个软件生命周期中所需要的大部分工具&#xff0c;如UML工具、代码管控工具、集成开发环境(IDE)等等&#xff0c;是最流行的Windows平台应用程序的集成开发环境。…

ESPHOME max7219点阵时钟

Note ESPHome中max7219digit驱动仅支持驱动点阵显示&#xff0c;对于7段数码管&#xff0c;请参考官方原文MAX7219 7-Segment Display。 本文参考自官方文档MAX7219 Digit Display 硬件连接 由于与MAX7219Digit的通信是使用SPI进行此集成的&#xff0c;因此您需要在配置中使用…

git国内下载

https://npm.taobao.org/mirrors/git-for-windows/点进去最新的最后一条 选择.exe文件点击

微信小程序之网络数据请求 wx:request的简单使用

网络数据请求 1. 网络数据请求 wx:request2. 请求格式3. 关闭request的合法检验 1. 网络数据请求 wx:request 出于安全性方面的考虑&#xff0c;小程序官方对数据接口的请求做出了两个限制&#xff1a;只能请求 HTTPS 类型的接口必须将接口的域名添加到信任列表中. 在自己的微…

数据备份与还原,(mysqldump,source)索引(index),创建视图(view)

一、备份与还原 /***************************样例表***************************/ CREATE DATABASE booksDB; use booksDB;CREATE TABLE books (bk_id INT NOT NULL PRIMARY KEY,bk_title VARCHAR(50) NOT NULL,copyright YEAR NOT NULL ); INSERT INTO books VALUES (11078…