JavaWeb——后端之登录功能

6. 登录功能

6.1 登录认证

只进行用户名和密码是否存在的操作

@Slf4j
@RestController
public class LoginController {@Autowiredpublic EmpService empService;@PostMapping("/login")public Result login(@RequestBody Emp emp) {log.info("{}员工登录", emp);Emp e = empService.login(emp);return e != null? Result.success(): Result.error("用户名或密码错误");}
}Emp login(Emp emp);@Override
public Emp login(Emp emp) {Emp e = empMapper.getByUsernameAndPassword(emp);return e;
}@Select("select * from emp where username = #{username} and password = #{password}")
Emp getByUsernameAndPassword(Emp emp);

问题:在未登录的情况下,也可以直接访问部门管理、员工管理等功能

6.2 登录校验

请求来的时候线进行登录校验,校验通过的话,执行业务;不通过就跳转到登录界面

在这里插入图片描述

1)会话技术

会话: 浏览器和服务器ide一次连接,一次会话中可以包含多次请求和响应

会话跟踪: 服务器需要识别多次请求是否来自同一浏览器,以便在同一次会话的多次请求间共享数据

会话跟踪方案:

  • 客户端会话跟踪技术:Cookie
  • 服务端会话跟踪技术:Session
  • 令牌技术

Cookie:

①特点

  • 浏览器第一次发送请求给服务器的时候,服务器自动将Cookie返回给浏览器
  • 浏览器自动将收到的Cookie存储在本地
  • 浏览器向服务器发送请求的时候,自动携带Cookie

②优点

HTTP协议中支持的技术,浏览器自动进行

在这里插入图片描述

③缺点

  • 移动端APP无法使用Cookie
  • 不安全,用户可以自己禁用Cookie(在浏览器的设置里面)
  • Cookie不能跨域(协议、IP/域名、端口)

Session:

①特点

  • 基于Cookie

②优点

  • 存储在服务器端,安全

    在这里插入图片描述

③缺点

  • 服务器集群环境下无法直接使用Session
  • Cookie的缺点

令牌技术:

①特点

字符串的形式,可以存储在任何容器中,不只是可以存储在Cookie中

②优点

  • 支持PC端、移动端
  • 解决集群环境下的认证问题
  • 减轻服务器端存储压力

在这里插入图片描述

③缺点

  • 需要自己实现

2)JWT令牌

全称:JSON Web Token(https://jwt.io/)

定义了一种**简洁(就是字符串)**的、**自包含(可以在其中包括用户名等需要的字符串)**的格式,用于在通信双方以json数据格式安全地传输信息。由于数字签名的存在,这些信息是可靠的

组成:

第一部分:Header(头),记录令牌类型、签名算法等;采用Base64编码

第二部分:Payload(有效荷载),携带一些自定义信息、默认信息等;采用Base64编码

第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload融入,并加入指定密钥,通过指定前面算法计算而来

例:

在这里插入图片描述

案例:

添加依赖

        <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
    // 生成JWTT@Testpublic void testGenJwt() {Map<String, Object> claims = new HashMap<>();claims.put("id", 1);claims.put("name", "tom");String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, "itheima")  // 签名算法和密钥.setClaims(claims)  // 自定义内容.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))  // 设置有效期为1h.compact();System.out.println(jwt);}// 解析JWT@Testpublic void testParseJwt() {Claims claims = Jwts.parser().setSigningKey("itheima")  // 密钥.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTcwNDY5Njg1NH0.MzTlN_jrVSa7UJtTFoXw4xQ9-t4R7JHUmHeom5KQ2ss").getBody();System.out.println(claims);}

错误

java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter

解决:

引入依赖

        <dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency>

登录-生成令牌

@Slf4j
@RestController
public class LoginController {@Autowiredpublic EmpService empService;@PostMapping("/login")public Result login(@RequestBody Emp emp) {log.info("{}员工登录", emp);Emp e = empService.login(emp);// 登录成功,生成令牌,下发令牌if (e != null) {Map<String, Object> claims = new HashMap<>();claims.put("id", e.getId());claims.put("name", e.getName());claims.put("username", e.getUsername());String jwt = JwtUtils.generateJwt(claims);  // jwt包含了当前登录的员工信息return Result.success(jwt);}// 登录失败,返回错误信息return Result.error("用户名或密码错误");}
}

3)过滤器Filter

概念: 过滤器是JavaWeb三大组件(Servlet、Filter、Listener)之一

功能: 把对资源的请求拦截下来,从而实现一些特殊功能,例如:登录校验、统一编码处理、敏感字符处理等

实现:

  • 实现Filter接口
  • @WebFilter(urlPatterns=“/*”)
  • @ServletComponentScan——让启动类知道
@WebFilter(urlPatterns = "/*")  // 拦截所有请求
public class DemoFilter implements Filter {@Override  // 初始化方法,只调用一次public void init(FilterConfig filterConfig) throws ServletException {System.out.println("init初始化方法执行了");}@Override  // 拦截到请求之后调用public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("拦截到了请求");// 放行filterChain.doFilter(servletRequest, servletResponse);}@Override  // 销毁方法,只调用一次public void destroy() {System.out.println("destroy销毁方法执行了");}
}

执行流程:

在这里插入图片描述

拦截路径:

在这里插入图片描述

过滤器链:

一个web应用有中,可以配置多个过滤器,多个过滤器就形成了一个过滤器链

顺序——注解配置的Filter,优先级是按照过滤器类名(字符串)的自然排序

在这里插入图片描述

@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// Tomcat传入的是request实际上是HTTPrequest,要进行强制类型转换HttpServletRequest req = (HttpServletRequest) servletRequest;HttpServletResponse resp = (HttpServletResponse) servletResponse;// 1. 获取请求urlString 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 jwt = req.getHeader("token");// 4. 判断令牌是否存在,如果不存在,返回错误结果(未登录)if (!StringUtils.hasLength(jwt)) {log.info("请求头token为空,返回未登录的信息");Result erro = Result.error("NOT_LOGIN");// 手动将Result对象转化为json格式——alibaba,fastJSONString notLogin = JSONObject.toJSONString(erro);resp.getWriter().write(notLogin);return;}// 5. 解析token,如果解析失败,返回错误结果(未登录)try {JwtUtils.parseJWT(jwt);} catch (Exception e) {e.printStackTrace();log.info("令牌解析失败,返回未登录错误信息");Result erro = Result.error("NOT_LOGIN");// 手动将Result对象转化为json格式——alibaba,fastJSONString notLogin = JSONObject.toJSONString(erro);resp.getWriter().write(notLogin);return;}// 6. 放行log.info("合法,放行");filterChain.doFilter(servletRequest, servletResponse);}
}

4)拦截器Interceptor

概念: 是一种动态拦截方法调用的机制,类似过滤器。Spring框架中提供的,用来动态拦截控制器方法的执行

作用: 拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码

@Component
public class LoginCheckInterceptor implements HandlerInterceptor {@Override  // 目标资源方法运行前运行,返回true:放行,返回false:不放行public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("preHandle ...");return true;}@Override  //目标资源方法运行后运行public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle ...");}@Override  // 视图渲染完毕后运行,最后才运行public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion ...");}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredpublic LoginCheckInterceptor loginCheckInterceptor;// 重写方法,注册拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");}
}

拦截路径:

在这里插入图片描述

执行流程:

在这里插入图片描述

Filter和Interceptor的区别:

  • 接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口
  • 拦截范围不同:过滤器Filter会拦截所有资源,而Interceptor只会拦截Spring环境中的资源

6.4 异常处理

方案一:在Controller的方法中进行try…catch处理

方案二:全局异常处理器

在这里插入图片描述

@RestControllerAdvice = @ControllerAdvice + @ResponseBody

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

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

相关文章

ASP .net core微服务实战

>>>>>>>>>>>>>>开发<<<<<<<<<<<<<<<< 0)用户 用户到nginx之间需要用https&#xff0c;避免被监听。 1)nginx // 做统一的分发&#xff0c;到微服务&#xff0c;相当于网关,提供统…

APP出海需知——Admob广告变现竞价策略

越来越多的出海公司更加重视应用的广告变现&#xff0c;Admob因其提供丰富的广告资源&#xff0c;稳定的平台支持&#xff0c;被广泛采用接入。 Admob广告变现策略 1、bidding竞价策略 Bidding目前是Admob广泛推广的较成熟的变现方案&#xff0c;当竞价网络和瀑布流混合时&a…

第二百五十四回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"如何给图片添加阴影"相关的内容&#xff0c;本章回中将介绍自定义Radio组件.闲话休提&#xff0c;让我们一起Talk Flutter吧…

socket通信实现TCP协议的同步通信

实现tcp通信&#xff0c;一般第一想到的是用netty框架&#xff0c;但是netty实现的通信一般是异步&#xff0c;发送消息后&#xff0c;不需要等到回复。 最近遇到一个需求时&#xff0c;与某个网关进行tcp通信&#xff0c;发送请求消息之后会立马回复&#xff0c;并且不同的请…

JAVA:解析Event事件机制与应用举例

1、简述 Java事件机制是一种基于观察者模式的设计模式&#xff0c;用于处理对象之间的松耦合通信。本篇技术博客将深入探讨Java事件机制的原理&#xff0c;并通过实际应用举例展示如何在项目中灵活利用该机制。 2、基本原理 Java事件机制基于观察者模式&#xff0c;包含以下…

【AI视野·今日NLP 自然语言处理论文速览 第六十七期】Mon, 1 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Mon, 1 Jan 2024 Totally 42 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Principled Gradient-based Markov Chain Monte Carlo for Text Generation Authors Li Du, Afra Amini, Lucas…

npm i sass -D的含义

命令 npm i sass -D 是一个在Node.js项目中使用npm&#xff08;Node Package Manager&#xff09;安装Sass预处理器的命令。这个命令的各个部分含义如下&#xff1a; npm: 这是Node Package Manager的缩写&#xff0c;一个用于Node.js的包管理和分发工具&#xff0c;允许开发者…

手把手教你学会接口自动化系列二-编写一个get接口

之前我们写了登录接口,对于登录的接口是post请求。 详见: 手把手教你学会接口自动化系列一-浅浅地尝试编写登录接口的自动化代码-CSDN博客 我们都知道接口最常用的两种类型是get和post类型,为了让知识完整性,我这节课演示下接口自动化如何请求get类型的接口,因为get类型…

C语言程序由哪些部分组成?

一、问题 一个C语言程序都由哪些部分组成? 它的基本单位是什么? 二、解答 一个 C语言程序可以由一个主函数和若干个函数构成。一个大的应用程序一般应该分为多个程序模块&#xff0c;每一个模块用来实现一个功能。实现这些模块功能的可以叫做子程序。 在 C 语言中&#xff…

职场必备技能2自动化办公excel操作

目录 一、介绍excel 二、应用场景&#xff1a;----可以完成什么操作 生活中遇见的场景 三、下载 四、excel模块 3.1、xlrd 语法&#xff1a; 案例&#xff1a; 算2020年与2021收入差距是多少 3.2、openpyxl 语法 案例1&#xff1a;计算一年的工资--12个月 案例2&…

探讨JS混淆技术及其加密解密实例

引言 在当前计算机科学领域中&#xff0c;保护软件代码的安全性和隐私性变得愈发重要。为了防止黑客攻击和恶意软件分析&#xff0c;开发人员采用各种技术来混淆和加密其代码&#xff0c;其中包括JS混淆技术。本文将介绍JS混淆技术的原理和应用&#xff0c;并提供一些相关的加密…

十、HTML 样式- CSS

CSS (Cascading Style Sheets) 用于渲染HTML元素标签的样式。 一、实例 1、HTML使用样式 本例演示如何使用添加到 <head> 部分的样式信息对 HTML 进行格式化。 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>HTM…

Spring Boot 和 Spring Framework 的区别

Spring Boot 和 Spring Framework (通常简称为 Spring) 有几个主要区别&#xff1a; 简化配置&#xff1a;Spring Boot 的一个主要目标是简化 Spring 应用的配置和启动过程。它提供了“约定优于配置”的原则&#xff0c;这意味着如果你遵循默认配置&#xff0c;你可以用更少的配…

用sql计算两个日期的间隔天数 ,去除周末

快递行业&#xff0c;经常需要计算2个节点的时效&#xff0c;有的计算自然日&#xff0c;有时候需要计算去掉周末的时效&#xff0c;计算自然日很简单&#xff0c;用函数datediff 就可以了&#xff0c;计算工作日时效&#xff0c;我的实现方法如下&#xff0c;借助了一个日期维…

多线程-生产者消费者模型

一、基本信息 1、场景介绍&#xff1a;厨师和吃货的例子&#xff0c;吃货吃桌子上的面条&#xff0c;吃完让厨师做&#xff0c;厨师做完面条放桌子上&#xff0c;让吃货吃&#xff0c;厨师如果发现桌子上有面条&#xff0c;就不做&#xff0c;吃货发现桌子上没有面条就不吃。 …

校招行测,认知能力测验,④破解数量关系测试题

数量关系&#xff0c;值得是数量计算、对比和分析&#xff0c;每种题型都有一定的规律性&#xff0c;如果善于终结也是容易掌握的&#xff0c;当然&#xff0c;只有见多&#xff0c;才能识广&#xff0c;最好的方式就是&#xff0c;锻炼&#xff0c;刷题&#xff0c;就算是临时…

socket从客户端向主机传输一个文件

client FileInputStream 是 Java 中用于从文件中读取字节流的类&#xff0c;它属于字节流的一部分。它主要用于读取原始的字节数据&#xff0c;例如图像、音频、文本文件等。FileInputStream 继承自 InputStream 类。 //将需要读取的文件变成可输出的流FileInputStream fileI…

QT应用篇:QT解析与生成XML文件的四种方式

四种常见的解析 XML 的方式(DOM、SAX、以及基于 Qt 的 XmlStreamReader)各有自己的优缺点,适合不同的应用场景。 DOM 适合小型且结构简单的 XML 文件,需要频繁修改和操作整个文档结构的情况。SAX 适合大型 XML 文件,以及只需读取不需要修改的情况。基于 Qt 的 XmlStreamRe…

12V 全桥驱动芯片GC9008——可替代TMI8118,应用于摄像机、消费类产品上

GC9008 是一款 12V 全桥驱动芯片&#xff0c;为提供高性价比的方案。它能提供 0.1A 的持续输出电流。可以工作在 4.5~15V 的电源电压上。 具有 PWM&#xff08;IN1/IN2&#xff09;输入接口,与行业标准器件兼容.是 SOP8封装&#xff0c;GC9008D是DIP封装芯片特点 ● H 桥电机驱…

使用 CompletableFuture 分批处理任务

一、无返回值任务函数 // 数据分批 List<List<StatisticsDTO>> batches Lists.partition(statisticsList, BATCH_SIZE); List<CompletableFuture<Void>> futures new ArrayList<>(batches.size());// 数据处理 for (int i 0; i < batches…