JavaEE Servlet03

news/2025/3/15 2:05:13/

目录

浏览器保存用户信息

路由导航守卫

路由嵌套

web会话跟踪机制

JWT生成token(json wen token)

起源

传统的session认证

基于session认证所暴露的问题

基于token的鉴权机制

JWT的主要应用场景

优点:

JWT的构成

第一部分:头部(header)

base64

第二部分:载荷(payload,用户的信息)

第三部分:签证(signature)

JWT搭建

java%EF%BC%8C%E6%89%80%E4%BB%A5%E9%9C%80%E8%A6%81%E7%9A%84%E6%98%AFjava-jwt-toc" name="tableOfContents" style="margin-left:80px">引入JWT依赖,由于是基于java,所以需要的是java-jwt

创建生成token的方法

JWT组件

验证token是否有效

axios请求拦截

token过滤器

响应拦截器

获得token中playload部分数据 


浏览器保存用户信息

会话期间存储,关闭浏览器后数据就会销毁
sessionStorage.setItem();

javascript">//在前端浏览器中存储用户信息
//会话期间存储,关闭浏览器后数据就会销毁
sessionStorage.setItem("account",resp.data.result.account);
sessionStorage.setItem("gender",resp.data.result.gender);
sessionStorage.setItem("phone",resp.data.result.phone);

效果

localStorage.setItem("","");
本地存储,即使关闭浏览器,下次打开还是存在,可以长久保存  

路由导航守卫

目前除了访问呢login.vue是不需要登录,除此之外的组件,都必须要登录后才能访问

使用vue-router中的路由导航守卫,在前端每次发生路由跳转时会触发拦截

判断访问哪些组件,哪些组件需要登录,哪些组件不需要登录

路由导航守卫,前端每发生一次路由跳转时,会自动触发beforeEach().

javascript">rout.beforeEach((to,from,next)=>{if(to.path=='/login'){//如果访问登录组件,不需要做任何判断,直接放行到目标组件去return next();//放行到目标文件}else{var token = window.sessionStorage.getItem("account");if(token==null){//用户信息为空,说明用户没有登录return next("/login");}else{//说明用户已经登录next();}}
})

目前只是在前端做了控制,后端同样需要进行控制

路由嵌套

在main路由下嵌套其他子路由

javascript"><template slot="title"><i class="el-icon-message"></i>操作菜单</template>
<el-menu-item-group> 
<el-menu-item index="/majorlist">专业管理</el-menu-item>
<!--路由地址-->
<el-menu-item index="/studentlist">学生管理</el-menu-item>
</el-menu-item-group> 

index.js导入组件

javascript">import MajorList from "../views/major/MajorList.vue";
import StudentList from "../views/student/StudentList.vue";

在el菜单上加一个router,这样我们的菜单是路由的

javascript"><el-menu :default-openeds="['1', '3']" router>

将major和student路由嵌套到main下

javascript">        {path: '/main',component: Main,children:[{path: "/majorlist",component: MajorList},{path: "/studentlist",component: StudentList}				]}

mian.vue

javascript"><el-main><router-view></router-view>
</el-main>

web会话跟踪机制

因为http请求是无状态的,一次强求响应结束后,就结束了

下一次再向服务器端发送请求,服务器并不知道是谁向它发送的

我们需要对整个会话过程进行跟踪:

1、当登录时,后端验证密码是否正确,如果账号正确,就需要在后端为当前登录的用户生成一个令牌(token)将令牌信息响应给前端

2、前端存储token

3、后面每一次从前端向后端发送请求都要携带token

4、后端验证令牌,如果令牌有效,继续向后执行,如果令牌无效,向前端响应失败,重新登录

JWT生成token(json wen token)

基于json的开放标准定义的一种简洁的,自包含的方法,用于通信双方以json对象的形式安全的传递信息。JWT可以使用HMAC算法或者是RSA是公私秘匙进行签名。

id-->token 秘匙-签名 

JWT就是用来生成token的方式,是一种可以携带用户信息,并且可以设置秘钥加密的字符串,是安全的。

起源

谈一谈基于token的认证和传统的session认证的区别

传统的session认证

将用户信息存储在服务器端,不好的地方:

1、占用服务器内存

2、分布式项目中,不灵活

基于session认证所暴露的问题

ssion: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大

扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

CSRF (跨站请求伪造):因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

基于token的鉴权机制

基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

流程上是这样的:

1. 用户使用账号和密码发出post请求;
2. 服务器使用私钥创建一个jwt;
3. 服务器返回这个jwt给浏览器;
4. 浏览器将该jwt串在请求头中像服务器发送请求;
5. 服务器验证该jwt;
6. 返回响应的资源给浏览器。

JWT的主要应用场景

可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。

由于信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。

优点:

1.简洁(Compact): 可以通过URLPOST参数或者在HTTP header发送,因为数据量小,传输速度也很快
2.自包含(Self-contained):负载中包含了所有用户所需要的信息,避免了多次查询数据库
3.因为Token是以JSON加密的形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持。
4.不需要在服务端保存会话信息,特别适用于分布式微服务。

JWT的构成

由三段信息构成,将三段信息文本用链接一起就构成了jwt字符串:

v51vdsvv45KJVHJUSVYD5VK.q3yqfy5q4qebshwny64w6q43t34y54qrtmanr3OH.AKCTW64XBVCSTXIcsDSbwhbvvonwqncpoi7h9p4

第一部分:头部(header)

jwt的头部承载两部分信息:

1、声明类型,这里是jwt

2、声明加密的方法:通常直接使用HMAC HS256

      完整的头部就像下面这样的JSON:

      {'typ':'JWT';'alg':'HS256'}-->重新进行编码

然后将头部进行base64转码,构成第一部分

v51vdsvv45KJVHJUSVYD5VK.

base64

链接:base64-CSDN博客

第二部分:载荷(payload,用户的信息)

存放有效信息的地方,形象理解为飞机上承载的货品,这些有效信息包含三个部分

1、标准中注册的声明

2、公共的声明

可以添加任何的信息。一般添加用户的相关信息或其他业务需要的必要信息/但不建议添加敏感信息(例如密码),因为该部分在客户端可解密。id,用户名,头像名  

3、私有的声明

      定义一个playload

      {"sub":"1234567890","name":"thesky","admin":true}

然后将头部进行base64转码,得到JWT第二部分

q3yqfy5q4qebshwny64w6q43t34y54qrtmanr3OH.

第三部分:签证(signature)

由三部分组成:

      header(base64后的)

      playload(base64后的)

      secret

需要base64转码后的header和base64转码后的playload使用连接组成新的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,构成jwt的第三部分

AKCTW64XBVCSTXIcsDSbwhbvvonwqncpoi7h9p4

JWT搭建

java%EF%BC%8C%E6%89%80%E4%BB%A5%E9%9C%80%E8%A6%81%E7%9A%84%E6%98%AFjava-jwt" name="%E5%BC%95%E5%85%A5JWT%E4%BE%9D%E8%B5%96%EF%BC%8C%E7%94%B1%E4%BA%8E%E6%98%AF%E5%9F%BA%E4%BA%8Ejava%EF%BC%8C%E6%89%80%E4%BB%A5%E9%9C%80%E8%A6%81%E7%9A%84%E6%98%AFjava-jwt">引入JWT依赖,由于是基于java,所以需要的是java-jwt

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.8.2</version>
</dependency>

创建生成token的方法

JWT组件
java">package com.ffyc.dormserver.util;import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.back.bean.User;
import com.ffyc.dormserver.model.Admin;import java.util.Date;
import java.util.HashMap;
import java.util.Map;/*** JWT工具类*/
public class JWTUtil {/*** 根据用户id,账号生成token* @param u* @return*/public static String getToken(Admin admin) {String token = "";try {//过期时间 为1970.1.1 0:0:0 至 过期时间  当前的毫秒值 + 有效时间Date expireDate = new Date(new Date().getTime() + 10*1000);//秘钥及加密算法Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");//设置头部信息Map<String,Object> header = new HashMap<>();header.put("typ","JWT");header.put("alg","HS256");//携带id,账号信息,生成签名token = JWT.create().withHeader(header).withClaim("id",admin.getId())//第二部分.withClaim("account",admin.getAccount())//第二部分.withExpiresAt(expireDate)//第二部分.sign(algorithm);//第三部分  秘钥  加盐}catch (Exception e){e.printStackTrace();return  null;}return token;}
}

后端获取token,将token响应给前端

java">            if(admin!=null){//登录成功后,为当前登录的用户生成tokenString token = JWTUtil.getToken(admin);admin.setToken(token);result = new Result<>(200,"登录成功",admin);}else{result = new Result<>(201,"账号或密码错误",null);}
javascript">sessionStorage.setItem("token",resp.data.result.token);

验证token是否有效

JWT组件

java">    /*** 验证token是否有效* @param token* @return*/public static boolean verify(String token){try {//验签Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");JWTVerifier verifier = JWT.require(algorithm).build();DecodedJWT jwt = verifier.verify(token);return true;} catch (Exception e) {//当传过来的token如果有问题,抛出异常return false;}}
axios请求拦截
javascript">//axios 请求拦截,每当我们使用axios框架向后端发送请求时,都会经过拦截器
axios.interceptors.request.use(config =>{//为请求头对象,添加 Token 验证的 token 字段config.headers.token = sessionStorage.getItem('token');return config;
})
token过滤器
java">package com.ffyc.dormserver.filter;import com.fasterxml.jackson.databind.ObjectMapper;
import com.ffyc.dormserver.model.Result;
import com.ffyc.dormserver.util.JWTUtil;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;/*验证token是否有效
*/
@WebFilter(urlPatterns = "/api/*")
public class TokenFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//向下转型HttpServletRequest request = (HttpServletRequest)servletRequest;//从请求头中拿到tokenString token = request.getHeader("token");System.out.println("token验证过滤器");//验证tokenboolean verify = JWTUtil.verify(token);if(verify){//token验证成功继续向后执行,到达目标servlet程序filterChain.doFilter(servletRequest, servletResponse);}else{//token验证失败向前端响应401Result result = new Result(401,"token认证失败",null);servletResponse.getWriter().print(new ObjectMapper().writeValueAsString(result));}}
}
响应拦截器
javascript">// 添加响应拦截器
axios.interceptors.response.use((resp) =>{//正常响应拦截if(resp.data.code==500){ElementUI.Message({message:resp.data.desc,type:"error"})}if(resp.data.code==401){ElementUI.Message({message:resp.data.desc,type:"error"})router.replace("/login");}return resp;
});
获得token中playload部分数据 
java">    /*** 获得token 中playload部分数据,按需使用* @param token* @return*/public static DecodedJWT getTokenInfo(String token){return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);}

http://www.ppmy.cn/news/1579200.html

相关文章

将docker images导入crictl images

在一些离线环境里&#xff0c;导入k8s镜像比较麻烦&#xff0c;可以通过以下方法导入镜像&#xff1a; 1、从 Docker 导出镜像为 tar 文件 docker save harbor.xxx.cn/nest-lib/test-csi:1.2.0 > test-csi-1.2.0.tar 2、导入镜像到 containerd ctr -nk8s.io images impo…

初阶数据结构(C语言实现)——5.3 堆的应用(1)——堆排序

目录 1 堆的应用1.1 堆排序1.1.1 思路1.1.2 代码实现 1.2 建堆的时间复杂度1.2.1 向下调整1.2.1 向上调整1.2.3 结论 学习堆的应用之前&#xff0c;欢迎学习下堆。 这是博主之前的文章&#xff0c;欢迎学习交流 初阶数据结构&#xff08;C语言实现&#xff09;——5.2 二叉树的…

用Python写一个算24点的小程序

一、运行界面 二、显示答案——递归介绍 工作流程&#xff1a; 1. 基本情况&#xff1a;函数首先检查输入的数字列表 nums 的长度。如果列表中只剩下一个数字&#xff0c;它会判断这个数字是否接近 24&#xff08;使用 abs(nums[0] - 24) < 1e-10 来处理浮点数精度问题&…

Haskell爬虫:为电商运营抓取京东优惠券的实战经验

一、需求分析&#xff1a;为什么抓取京东优惠券&#xff1f; 京东作为中国领先的电商平台之一&#xff0c;拥有海量的商品和丰富的优惠券资源。这些优惠券信息对于电商运营者来说具有极高的价值。通过分析竞争对手的优惠券策略&#xff0c;运营者可以更好地制定自己的促销方案…

如何利用Python爬虫获取微店商品详情数据:实战指南

微店作为知名的电商平台&#xff0c;提供了丰富的商品资源。通过Python爬虫技术&#xff0c;可以高效地获取微店商品的详情数据&#xff0c;用于数据分析、研究或其他用途。本文将详细介绍如何使用Python编写爬虫程序&#xff0c;获取微店商品的详情数据&#xff0c;并确保爬虫…

TCP/IP原理详细解析

前言 TCP/IP是一种面向连接&#xff0c;可靠的传输&#xff0c;传输数据大小无限制的。通常情况下&#xff0c;系统与系统之间的http连接需要三次握手和四次挥手&#xff0c;这个执行过程会产生等待时间。这方面在日常开发时需要注意一下。 TCP/IP 是互联网的核心协议族&…

用 DeepSeek 构建 Vue.js 底层架构:高效协作与问题解决实践

文章目录 1. **DeepSeek 与 Vue.js 的完美协作**2. **问题背景**3. **问题分析与解决**3.1 **动态路由未正确生成**3.2 **路由路径配置错误**3.3 **路由嵌套问题**3.4 **通配符路由未配置** 4. **DeepSeek 的核心价值** 在现代前端开发中&#xff0c;Vue.js 以其简洁的语法和灵…

一个差劲的软件设计

项目概况&#xff1a; 之前自己设计并开发了一个用C#开发的上位机软件&#xff0c;整个软件只有一个Form&#xff0c;一个TabControl&#xff0c;3个TabControlPanel&#xff0c;总共100多个lable、textbox、ListBox等控件都放在这3个TabControlPanel里。 问题&#xff1a; 1.…