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.hqwc.cn/news/334268.html

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

相关文章

【案例实战】业务稳定性运行之全链路混合压测

1.全链路压测开展步骤 &#xff08;1&#xff09;什么是全链路压测 全链路压测是指基于真实业务场景&#xff0c;通过模拟海量的用户请求&#xff0c;对整个后台服务进行压力测试&#xff0c;从而评估整个系统的性能水平。 对应用程序的整个技术栈进行完整的压力和性能测试&a…

C++|19.C++类与结构体对比

类和结构体 类和结构体本质上并没有太大区别。 但两者在默认上有所区别。 类默认成员变量是私有的&#xff0c;而结构体默认成员变量是公有的。 也就是说&#xff0c;对于一个类来说&#xff0c;会默认使用private去保护其内部成员变量使得无法直接访问到其内部的变量。 同时从…

外汇天眼:台北妇女轻信假投资诈骗话术,小赚1万却惨赔1500万

当今社会物价急速上涨&#xff0c;许多民众为了避免资产因通膨缩水&#xff0c;纷纷开始寻找各种能增加收入的渠道&#xff0c;因此投资理财日渐受到重视。 然而&#xff0c;诈骗集团也注意到这趋势&#xff0c;并且推出虚假的投资平台或方案&#xff0c;以各种话术行骗。 不久…

人逢三六九,运势低迷路难走

很多人都希望自己各方面的运势都能够朝着好的方向旺盛发展&#xff0c;我们的运势将会如何发展跟我们的出生时间是离不开关系的。我们的祖先为了后人着想&#xff0c;不犯他们犯过的错误&#xff0c;少走一些弯路&#xff0c;总结了多年来的生活经验&#xff0c;创造出了一句句…

在视频号上开通店铺怎么样?全新带货平台,普通人最后的电商机会

我是王路飞。 好消息&#xff1a;现在视频号上也可以开店、带货、做电商了。 坏消息&#xff1a;有一定的门槛&#xff08;尤其是资金方面&#xff09;。 视频号小店代表的是“全村的希望”&#xff08;腾讯马老板在22年底内部员工大会上的发言内容&#xff09;&#xff0c;…

Vue使用printJS导出网页为pdf、printJS导出pdf

先放几个参考链接 感谢&#xff01; Vue使用PrintJS实现页面打印功能_vue print.js 设置打印pdf的大小-CSDN博客 前台导出pdf经验汇总 &#xff08;html2canvas.js和浏览器自带的打印功能-print.js&#xff09;以及后台一些导出pdf的方法_iqc后台管理系统怎么做到导出pdf-CSD…

互联网外包公司干了2个月,技术退步明显了.......

先说一下自己的情况&#xff0c;本科毕业&#xff0c;18年通过校招进入南京某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能…

Aging:浙大学者研究发现,多吃这类抗氧化饮食,延缓衰老

撰文 | 宋文法 衰老&#xff0c;是一个复杂、多阶段、渐进的过程&#xff0c;发生在生命的整个过程。随着时间的流逝&#xff0c;人体的器官、肌肉会逐渐衰老&#xff0c;一些疾病也伴随着年龄的增长而发生&#xff0c;包括癌症、糖尿病、心血管疾病等。 衰老过程是由体内自由基…

【node link】Node命令中的node link命令的使用,还有CLI全局命令的使用,开发命令行工具必不可少的部分

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;NodeJs &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继续前进的勇气…

synchronized和lock的区别

synchronized和lock的区别 1&#xff09;synchronized是一个关键字&#xff0c;lock是一个java类&#xff1b; 2&#xff09;synchronized无法判断获取锁的状态&#xff0c;lock可以判断是否获取到了锁&#xff1b; 3&#xff09;synchronized会自动释放锁&#xff0c;lock必须…

ORPC-824,对标可替代ACPL-824/PC824等

提供隔离反馈 逻辑电路之间的接口 电平转换 DC和AC输入 SMPS中的调节反馈电路 消除接地环路 特征 电流传输比 &#xff08; CTR &#xff1a; 最低 20% 在 IF 1mA&#xff0c; VCE 5V &#xff09; 宽工作温度范围 -55~110C 高输入输出隔离电压 &#xff08; Viso 5&am…

LowB三人组(冒泡排序,插入排序,选择排序)(数据结构课设篇1,python版)(排序综合)

本篇博客主要详细讲解一下LowB三人组排序&#xff0c;为什么叫LowB三人组呢&#xff1f;因为他们的时间复杂度都为O&#xff08;n^2&#xff09;。下篇博客NB三人组&#xff08;堆排序&#xff0c;归并排序&#xff0c;快速排序&#xff09;&#xff08;数据结构课设篇2&#x…