web登录校验

devtools/2024/11/13 5:33:14/

基础登录功能

在这里插入图片描述
LoginController

@PostMapping("/login")Result login(@RequestBody Emp emp) {log.info("前端,发送了一个登录请求");Emp e = empService.login(emp);return e!=null?Result.success():Result.error("用户" +"名或密码错误");}

Service

@Overridepublic Emp login(Emp emp) {return empMapper.login(emp);}

DAO

   @Select("SELECT * From emp WHERE username=#{username} and" +"password=#{password}")Emp login(Emp emp);

利用Postman进行校验
在这里插入图片描述
乱输得用户名和密码.

退出后,访问相应地页面的url,直接进入了系统的页面.这时候用户名和密码就变得没有意义.

这时候就需要进行登录校验

登录校验

在这里插入图片描述

会话技术

在这里插入图片描述
令牌技术是当前企业开发中最主流的技术

会话跟踪

在这里插入图片描述

在请求时,后端自动给访问的浏览器生成了一个cookie并通过响应头{set-cookie}返回给浏览器。此后浏览器每次发送请求都会向浏览器自动发送这个cookie(cookie请求头)

Cookie
//设置cookie@GetMapping("/c1")public Result cookie(HttpServletResponse response) {// Cookie参数也是一个键值对response.addCookie(new Cookie("logusername","jzr10086"));return Result.success();}

发送请求 http://localhost:8080/c1
在这里插入图片描述
响应头中set-cookie头被设置为指定的参数

获取Cookie
//获取cookie@GetMapping("/c2")public Result cookie2(HttpServletRequest request) {Cookie[] cookies = request.getCookies();for(Cookie cookie : cookies) {if(cookie.getName().equals("logusername")) {System.out.println(cookie.getName()+cookie.getValue());}}return Result.success();}

在这里插入图片描述

访问c2时携带了对应的cookie,这样就建立了一次会话,当服务器停止运行或者浏览器关闭才会结束会话。
在这里插入图片描述

跨域:

在这里插入图片描述
这时候如果服务器端要设置cookie将无法使用。因为服务器端无法跨域访问到前端。

Session

设置Session
//设置session@GetMapping("/s1")public Result session(HttpSession session) {log.info("Http-session-s1:{}" , session.hashCode());session.setAttribute("logusername","jzr10086");return Result.success();}

访问 localhost:8080/s1
在这里插入图片描述
Set-Cookie是Session对象的id;

cookie储存在本地浏览器上
session储存在服务器上

获取Session
//获取session@GetMapping("/s2")public Result session2(HttpSession session) {log.info("Http-session-s2:{}" , session.hashCode());Object obj = session.getAttribute("logusername");log.info("session2:{}" , obj.toString());return Result.success();}

访问s2:
在这里插入图片描述
两次请求的hashcode相同,说明两次请求共用了一个session
在这里插入图片描述

同一个浏览器发送的请求可能被负载均衡服务器转到不同的后端服务器上,导致后端服务器找不到对应的session对象
在这里插入图片描述
在这里插入图片描述

JWT令牌

在这里插入图片描述
缺点:需要自己实现令牌的生成检验等操作

服务端在浏览器请求之后,生成一个令牌并传送给浏览器。此后每次请求都会有服务端校验令牌的有效性。

在这里插入图片描述
在这里插入图片描述

生成校验JWT

依赖:
在这里插入图片描述

		<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>

在这里插入图片描述

@Testvoid testGenJwt() {claims.put("id","1");claims.put("name","test");String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256,"jzr666") //生成JWT令牌使用的算法和密钥.setClaims(claims) //自定义内容(载荷).setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) //设置有效期.compact(); //按照要求生成对应的数字令牌System.out.println(jwt);}

在这里插入图片描述
运行单元测试类,生成了对应的令牌。
可以通过公钥解密之后看到对应的JWT令牌内容,但是内容不可被更改。对应得JWT令牌不可被伪造。
·
利用对应的密钥进行解码

 @Testvoid praseJwt(){Claims claim = Jwts.parser().setSigningKey("jzr666") //指定签名密钥.parseClaimsJwt("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidGVzdCIsImlkIjoiMSIsImV4cCI6MTcyNTY4Mjk1NH0.O3q9xHqoMJAf1Pm1vdmmUzADXsUsBoQLaKa-Vc3bVsQ") //注意是jws不是jwt.getBody();System.out.println(claim);}

获取到了载荷中存放的内容
在这里插入图片描述
如果篡改令牌中的任意一个字符,在解析的时候都会报错。令牌过期之后,解析也会报错

登陆后下发令牌

在这里插入图片描述
通过Result响应以Json格式返回给前端
在这里插入图片描述
以后前端在每次请求时,都会将令牌携带到服务端(通过请求头的token)。

过滤器Filter

在这里插入图片描述
在这里插入图片描述

快速入门

在这里插入图片描述

实现接口并重写三个方法:
在这里插入图片描述
在启动类中加入ServletComponentScan,因为Filter组件并不属于SpringBoot的内容

package com.yuyu.realproject.Filter;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;import java.io.IOException;//表示拦截所有请求
@WebFilter("/*")
public class DemoFilter implements Filter {@Override//初始化方法,只调用一次public void init(FilterConfig filterConfig) throws ServletException {System.out.println("Init初始化方法执行了");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("doFilter初始化方法执行了");//调用doFilter方法放行,继续访问对应的资源filterChain.doFilter(servletRequest, servletResponse);}@Override //销毁方法,只调用一次public void destroy() {System.out.println("拦截到了请求");}
}

在请求之前的emps查询接口时,首先被doFilter函数拦截,然后执行filterChain的doFilter操作放行,然后开始执行查询操作
在这里插入图片描述
从控制台的日志中可以看到idoFilter函数的执行过程
在这里插入图片描述
记得要再过滤器的Controller类上加上WebFilter注解。

详解
执行流程

1.放行前逻辑
2.放行操作,进行前端请求的操作
3.执行完毕,放行后逻辑
在这里插入图片描述
在这里插入图片描述

拦截路径

在这里插入图片描述

过滤器链

在这里插入图片描述
在这里插入图片描述

DoFilter实际上是将当前的服务放行到下一个过滤器,如果后面没有过滤器了,则访问对应的web资源

类名在软件包中排名越靠前,越早执行。由于Java类在软件包中按照字符串的顺序进行排序,所以只需要重构类名,就能得到所需要的执行顺序。
在这里插入图片描述
小结:
在这里插入图片描述

登录校验(利用过滤器实现)

在这里插入图片描述
1.执行登录请求时并不需要Jwt令牌
2.Jwt令牌存在且有效就允许放行

过程:
在这里插入图片描述
登录检验过滤器的实现

package com.yuyu.realproject.Filter;import com.alibaba.fastjson.JSONObject;
import com.yuyu.realproject.Pojo.Result;
import com.yuyu.realproject.utils.JwtUtils;
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.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import java.io.IOException;@Slf4j
@WebFilter("/*")
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//获取请求和响应对象HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;String url = request.getRequestURI().toString();if (url.contains("login")) {log.info("登录请求,直接放行");filterChain.doFilter(request, response);return;}String Jwt = request.getHeader("token");if(StringUtils.hasLength(Jwt)){log.info("请求头中没有相应地令牌");Result error = Result.error("not login in");//手动转换json对象,使用阿里的fastjson工具包String notlogin = JSONObject.toJSONString(error);//直接将登录失败的信息相应给浏览器response.getWriter().write(notlogin);return;}try{JwtUtils.praseJwt(Jwt);}catch (Exception e){e.printStackTrace();log.info("当前令牌无效");Result error = Result.error("not login in");//手动转换json对象,使用阿里的fastjson工具包String notlogin = JSONObject.toJSONString(error);//直接将登录失败的信息相应给浏览器response.getWriter().write(notlogin);return;}//如果登录成功,直接放行filterChain.doFilter(request,response);}
}

e.printStackTrace()是 Java 中的一种异常处理机制中的语句。
以下是关于它的详细解释:
基本含义
在 Java 编程中,当程序运行过程中发生异常(Exception)时,可以通过try - catch语句块来捕获异常。e.printStackTrace()通常放在catch块中,其中e是捕获到的异常对象。它的主要作用是打印异常的堆栈跟踪信息。

前端看到Not_login标识会自动重定向到登录页面。 也就是说这步操作是在前端实现的

拦截器Interceptor

拦截器和Fillter的区别在于是由Spring提供的?
在这里插入图片描述
在这里插入图片描述
1.进行HandlerInterceptor的实现

@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {//按ctrl+o进行生成//目标资源方法运行前运行,返回true放行,返回false不放行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println ("preHandler 运行了");return true;}//目标资源方法运行后运行@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println ("postHandler 运行了");}@Override //视图渲染完成后运行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println ("运行完了");}
}

2.进行拦截器的配置,添加拦截器,记得加上configuration注解

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;//添加拦截器的配置@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor (loginInterceptor).addPathPatterns("/**");}
}

在这里插入图片描述
从日志中可以看到,拦截器的preHandler首先执行,return true之后,放行进入登录的Controller,执行结束后执行postController。当所有操作结束之后,这个请求由一个afterCompletion进行终结
在这里插入图片描述

拦截路径的配置:
在这里插入图片描述
不同拦截路径的配置
在这里插入图片描述
在这里插入图片描述

过滤器和拦截器的区别

当过滤器和拦截器同时存在时:

登录校验:
和过滤器的逻辑基本类似。

异常处理

在这里插入图片描述
出现异常的时候,返回的异常并不符合开发文档中定义的错误,所以前端无法对这样的异常进行处理。

如果需要新增的部门已经存在,由于部门表中用部门名称作为主键,sql的insert语句会报错,服务器会返回500错误。但是前端不抓包的话并不会发现这样的错误。

在这里插入图片描述

方案:全局异常处理器

在这里插入图片描述
在这里插入图片描述
加上RestControllerAdvice注解,在捕获异常的方法中要加上ExceptionHandler注解
在这里插入图片描述
这样所有的异常都会返回异常的Json数据。
这个注解包含ResponseBody,会将返回的对象转化为Json格式,所以不需要自己手动转换

@RestControllerAdvice
public class exceptionHandler {@ExceptionHandler(Exception.class)public Result ex(Exception e){e.printStackTrace ();return Result.error ("服务访问失败,请练习管理员");}}

这样就把异常转化成了前端可以处理的Result
在这里插入图片描述


http://www.ppmy.cn/devtools/108633.html

相关文章

H5小程序开发怎么挑选服务器

H5小程序开发怎么挑选服务器&#xff1f;在移动互联网的浪潮中&#xff0c;H5小程序以其跨平台、易传播、开发成本低等优势&#xff0c;迅速成为企业拓展线上业务的重要工具。然而&#xff0c;一个优秀的H5小程序背后&#xff0c;离不开稳定、高效的服务器支持。服务器作为小程…

CSDN文章无水印转成PDF

文章目录 一、打开检查二、点击进入控制台三、在控制台中输入代码 一、打开检查 f11或者右键打开检查 二、点击进入控制台 三、在控制台中输入代码 (function(){ use strict;var articleBox $("div.article_content");articleBox.removeAttr("style&quo…

std::unordered_set与unordered_map

C unordered_map / map中&#xff0c;key/val的类型问题。_unorderedmap<string, vector<int>>-CSDN博客 C11 新特性&#xff1a;std::unordered_set 无序集合_std set 无序集合-CSDN博客

软件测试基础总结+面试八股文

一、什么是软件&#xff1f; 软件是计算机系统中的程序和相关文件或文档的总称。 二、什么是软件测试&#xff1f; 说法一&#xff1a;使用人工或自动的手段来运行或测量软件系统的过程&#xff0c;以检验软件系统是否满足规定的要求&#xff0c;并找出与预期结果之间的差异…

在Go语言中,不同类型之间转换的一些主要方法:

在Go语言中&#xff0c;类型转换是非常常见的操作。以下是不同类型之间转换的一些主要方法&#xff1a; 1. 基本类型转换 基本类型包括整型、浮点型、复数、字符串等。 整型到浮点型: var i int 10 var f float64 float64(i)浮点型到整型 (会丢失小数部分): var f float64 …

注册安全分析报告:熊猫频道

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

论文笔记: 智能电力系统综述

摘要 电力调度是智能电网运行的一大核心问题&#xff0c;其目的是在满足时空变化的电力负荷条件下提供电网的最优运行点。这一功能需要在一天内每隔几分钟运行一次&#xff0c;因此快速、准确的调度决策方法至关重要。但是&#xff0c;由于问题的复杂性&#xff0c;可靠且高效…

Pixelmator Pro for Mac 专业图像处理软件【媲美PS的修图软件】

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功 三、运行测试安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件…