java后端之登录认证

在这里插入图片描述

  • 基础登录功能:根据提供的用户名和密码判断是否存在于数据库
    LoginController.java
@RestController
@Slf4j
public class LoginController {@Autowiredprivate UserService userService;@PostMapping("/login")public Result login(@RequestBody User user) {log.info("user: {}", user);User u = userService.login(user);return u != null ? Result.success(u) : Result.error("用户名或密码错误");}
}

UserController.java


@Service
public class UserServiceImpl implements com.diaryback.Service.UserService {@Autowiredprivate UserMapper userMapper;public User login(User user) {return userMapper.getUserByIdAndPassword(user);}
}

登录校验

在用户未登录情况下访问需要登录才能使用的业务,会跳转到登录界面
在这里插入图片描述

会话技术

  • 会话:用户通过浏览器访问服务器资源时建立会话,直到一方断开连接会话结束。一次会话中可以包含多次请求和响应
  • 会话跟踪:服务器需要识别多个请求是否来自同一个浏览器,以便在同一个会话的多个请求之间共享数据

Cookie

服务器端存储Cookie,响应时自动加上Cookie到客户端,客户端下次请求会自动加上cookie
不允许跨域请求
在这里插入图片描述

Session

Session技术基于cookie,首次访问服务端时创建session,并将sessionID附加到cookie
在这里插入图片描述

令牌

令牌中存储用户的身份信息以及需要共享的数据,存储在客户端
在这里插入图片描述

JWT令牌

jwt:JSON Web Token,将原始JSON数据进行安全封装
jwt三组成部分:

  • Header:记录令牌类型,签名算法
  • Payload:有效载荷,携带自定义信息,默认信息和有效期等
  • Signature:签名,确保安全性。将header和payload加密计算而来

引入依赖:

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

生成jwt字符串:需要指定签名算法、密钥以及自定义内容和过期时间

    /*** 测试生成JWT*/@Testpublic void testGenJWT(){Map<String, Object> claims = new HashMap<>();claims.put("id", 1);claims.put("name", "maria");String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, "AlexandarHamiltonWeAreWaitingInTheWingsForYou")//设置加密方式和加密密钥.claims(claims)//设置自定义内容.expiration(new Date(System.currentTimeMillis() + 3600 * 1000))//设置有效期为一个小时.compact();//生成字符串System.out.println(jwt);}

解析时需要指定签名的密钥

    /*** 测试解析JWT*/@Testpublic void testParseJWT() {Claims claims = Jwts.parser().setSigningKey("AlexandarHamiltonWeAreWaitingInTheWingsForYou")//设置解密密钥.build().parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoibWFyaWEiLCJpZCI6MSwiZXhwIjoxNzM3NzExMjQ3fQ.AD2hdUzHdzq9qA0ZulvOyWA857tuRUWChnEX2P1ebcI").getBody();System.out.println(claims);}

JWT工具类:jwtUtil

package com.diaryback.Utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;
import java.util.Map;public class JwtUtil {private static String signKey = "AlexandarHamiltonWeAreWaitingInTheWingsForYou";private static Long expire = 432000000L;/*** 生成jwt令牌*/public static String generateJwt(Map<String, Object> claims){String jwt = Jwts.builder().addClaims(claims).signWith(SignatureAlgorithm.HS256, signKey).setExpiration(new Date(System.currentTimeMillis() + expire)).compact();return jwt;}/*** 解析jwt令牌*/public static Claims parseJwt(String jwt){Claims claims = Jwts.parser().setSigningKey(signKey).build().parseClaimsJws(jwt).getBody();return claims;}
}

Filter过滤器

可以拦截对资源的请求,通常用于登录校验、统一编码等

  • 定义Filter:定义一个类,实现Filter接口,重写所有方法(init(), destroy(), doFilter())
  • 配置Filter:Filter类加上@WebFilter注解,配置拦截资源的路径,同时启动类加上@ServletComponentScan开启Servlet组件支持

拦截路径的配置:
在这里插入图片描述
过滤器链:一个web应用中可以配置多个过滤器行程过滤器链

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;import javax.servlet.*;
import java.io.IOException;@WebFilter(urlPatterns = "/*")
public class DemoFilter implements jakarta.servlet.Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {
//        Filter.super.init(filterConfig);System.out.println("初始化过滤器");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("Demo 执行过滤操作...放行前逻辑");//放行filterChain.doFilter(servletRequest, servletResponse);System.out.println("Demo 执行过滤操作...放行后逻辑");}@Overridepublic void destroy() {
//        Filter.super.destroy();System.out.println("销毁过滤器");}
}

登录校验的Filter流程:
在这里插入图片描述
LoginFilter.java

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONPObject;
import com.diaryback.Pojo.Result;
import com.diaryback.Utils.JwtUtil;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.http.HttpRequest;@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) servletRequest;//强制类型转换,将ServletRequest转换为其子类HttpServletRequestHttpServletResponse resp = (HttpServletResponse) servletResponse;String url = req.getRequestURL().toString();log.info("请求的url:{}", url);// 如果是登录请求则放行if(url.contains("login")){log.info("登录请求,放行");filterChain.doFilter(servletRequest, servletResponse);return;}//获取请求头中的令牌String jwt = req.getHeader("token");//判断请求头中是否有令牌if(!StringUtils.hasLength(jwt)){log.info("未登录,不允许访问");Result error = Result.error("NOT_LOGIN");//将Result转换为JSON格式传递给前端,使用fastJson包String notLogin = JSON.toJSONString(error);resp.getWriter().write(notLogin);return;}//解析token校验令牌try {JwtUtil.parseJwt(jwt);} catch (Exception e) {//jwt解析失败e.printStackTrace();log.info("解析失败,不允许访问");Result error = Result.error("NOT_LOGIN");String notLogin = JSON.toJSONString(error);resp.getWriter().write(notLogin);return;}//放行log.info("已登录,放行");filterChain.doFilter(servletRequest, servletResponse);}
}

Interceptor拦截器

Interceptor:作用类似于Filter,拦截请求,在指定方法调用前后执行预先设定的代码

  • 定义拦截器,实现HandlerInterceptor接口,并重写所有方法(preHandler, postHandle, afterCompletion)
  • 注册拦截器,需要在配置类中注册

LoginCheckInterceptor.java

package com.diaryback.Interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;@Component //将拦截器交给Spring容器管理
public class LoginCheckInterceptor implements HandlerInterceptor {@Override //请求处理前调用,返回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执行");}
}

WebConfig.java

package com.diaryback.config;import com.diaryback.Interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration //声明是配置类
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginCheckInterceptor loginCheckInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//添加拦截器registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");}
}

拦截路径:addPathPatterns()定义需要拦截哪些资源,excludePathPatterns()定义不需要拦截哪些资源
在这里插入图片描述
拦截器执行流程:
在这里插入图片描述
登录校验拦截器


```java
package com.diaryback.Interceptor;import com.alibaba.fastjson.JSONObject;
import com.diaryback.Pojo.Result;
import com.diaryback.Utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;@Slf4j
@Component //将拦截器交给Spring容器管理
public class LoginCheckInterceptor implements HandlerInterceptor {@Override //请求处理前调用,返回false则请求不会被处理public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String url = request.getRequestURL().toString();log.info("preHandle执行,url: {}", url);if(url.contains("login")){log.info("放行");return true;}String jwt = request.getHeader("token");//检查是否有令牌if(!StringUtils.hasLength(jwt)){log.info("未登录");Result error = Result.error("NOT_LOGIN");String notLogin = JSONObject.toJSONString(error);response.getWriter().write(notLogin);return false;}//解析令牌try {JwtUtil.parseJwt(jwt);} catch (Exception e) {e.printStackTrace();log.info("令牌无效");Result error = Result.error("NOT_LOGIN");String notLogin = JSONObject.toJSONString(error);response.getWriter().write(notLogin);return false;}//放行log.info("放行");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执行");}
}

异常处理

定义全局异常处理器
在这里插入图片描述


import com.diaryback.Pojo.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** 全局异常处理*/
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)//指定处理的异常类型public Result ex(Exception ex){ex.printStackTrace();return Result.error("服务器异常");}
}

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

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

相关文章

嵌入式知识点总结 Linux驱动 (七)-Linux驱动常用函数 uboot命令 bootcmd bootargs get_part env_get

针对于嵌入式软件杂乱的知识点总结起来&#xff0c;提供给读者学习复习对下述内容的强化。 目录 1.ioremap 2.open 3.read 4.write 5.copy_to_user 6.copy_from_user 7.总结相关uboot命令以及函数 1.bootcmd 1.1.NAND Flash操作命令 2.bootargs 2.1 root 2.2 rootf…

DS并查集(17)

文章目录 前言一、何为并查集&#xff1f;二、并查集的实现&#xff1f;并查集的初始化查找元素所在的集合判断两个元素是否在同一个集合合并两个元素所在的集合获取并查集中集合的个数并查集的路径压缩 三、来两道题练练手&#xff1f;省份的数量等式方程的可满足性 总结 前言…

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<2>

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。 今天我们来学习const修饰指针&#xff0c;包括const修饰变量&#xff0c;const修饰指针变量&#xff1b…

DeepSeek 云端部署,释放无限 AI 潜力!

1.简介 目前&#xff0c;OpenAI、Anthropic、Google 等公司的大型语言模型&#xff08;LLM&#xff09;已广泛应用于商业和私人领域。自 ChatGPT 推出以来&#xff0c;与 AI 的对话变得司空见惯&#xff0c;对我而言没有 LLM 几乎无法工作。 国产模型「DeepSeek-R1」的性能与…

小程序的数据绑定与事件绑定

1.数据绑定的基本原则 2.在data中定义页面的数据 3.Mustache语法的格式 &#xff08;其实可以把他理解为插值表达式&#xff09; 动态绑定属性 三元运算 算数运算 4.事件绑定 事件绑定基本使用

实验一---典型环节及其阶跃响应---自动控制原理实验课

一 实验目的 1.掌握典型环节阶跃响应分析的基本原理和一般方法。 2. 掌握MATLAB编程分析阶跃响应方法。 二 实验仪器 1. 计算机 2. MATLAB软件 三 实验内容及步骤 利用MATLAB中Simulink模块构建下述典型一阶系统的模拟电路并测量其在阶跃响应。 1.比例环节的模拟电路 提…

Git进阶之旅:Git 多人合作

项目克隆&#xff1a; git clone 仓库地址&#xff1a;把远程项目克隆到本地形成一个本地的仓库 克隆下来的仓库和远程仓库的名称一致 注意&#xff1a;git clone 远程仓库地址 远程仓库名&#xff1a;把远程仓库克隆下来&#xff0c;并自定义仓库名 多人协作&#xff1a; …

Baklib赋能企业实现高效数字化内容管理提升竞争力

内容概要 在数字经济的浪潮下&#xff0c;企业面临着前所未有的机遇与挑战。随着信息技术的迅猛发展&#xff0c;各行业都在加速推进数字化转型&#xff0c;以保持竞争力。在这个过程中&#xff0c;数字化内容管理成为不可或缺的一环。高效的内容管理不仅能够优化内部流程&…

【C++ 数学 括号匹配】2116. 判断一个括号字符串是否有效|2037

本文涉及知识点 数学 括号匹配 LeetCode2116. 判断一个括号字符串是否有效 一个括号字符串是只由 ‘(’ 和 ‘)’ 组成的 非空 字符串。如果一个字符串满足下面 任意 一个条件&#xff0c;那么它就是有效的&#xff1a; 字符串为 (). 它可以表示为 AB&#xff08;A 与 B 连接…

计算机毕业设计Python+CNN卷积神经网络考研院校推荐系统 考研分数线预测 考研推荐系统 考研爬虫 考研大数据 Hadoop 大数据毕设 机器学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

仿真设计|基于51单片机的温室环境监测调节系统

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现&#xff08;protues8.7&#xff09; 程序&#xff08;Keil5&#xff09; 全部内容 资料获取 具体实现功能 &#xff08;1&#xff09;LCD1602液晶第一行显示当前的光照值及二氧化碳浓度值&#xff0c;第二…

智慧园区如何利用智能化手段提升居民幸福感与环境可持续性

内容概要 在当今社会&#xff0c;随着城市化进程的加快&#xff0c;智慧园区作为一种新兴的城市管理模式&#xff0c;逐渐获得了人们的关注。智慧园区不仅仅是物理空间的规划&#xff0c;更是一种通过智能化手段提升居民幸福感与环境可持续性的综合解决方案。本段将对智慧园区…

Android --- CameraX讲解

预备知识 surface surfaceView SurfaceHolder surface 是什么&#xff1f; 一句话来说&#xff1a; surface是一块用于填充图像数据的内存。 surfaceView 是什么&#xff1f; 它是一个显示surface 的View。 在app中仍在 ViewHierachy 中&#xff0c;但在wms 中可以理解为…

NLP深度学习 DAY5:Sequence-to-sequence 模型详解

Seq2Seq&#xff08;Sequence-to-Sequence&#xff09;模型是一种用于处理输入和输出均为序列任务的深度学习模型。它最初被设计用于机器翻译&#xff0c;但后来广泛应用于其他任务&#xff0c;如文本摘要、对话系统、语音识别、问答系统等。 核心思想 Seq2Seq 模型的目标是将…

Java锁自定义实现到aqs的理解

专栏系列文章地址&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标&#xff1a; 理解锁&#xff0c;能自定义实现锁通过自定义锁的实现复习Thread和Object的相关方法开始尝试理解Aqs, 这样后续基于Aqs的的各种实现将能更好的理解 目录 锁的…

基于STM32的阿里云智能农业大棚

目录 前言&#xff1a; 项目效果演示&#xff1a; 一、简介 二、硬件需求准备 三、硬件框图 四、CubeMX配置 4.1、按键、蜂鸣器GPIO口配置 4.2、ADC输入配置 4.3、IIC——驱动OLED 4.4、DHT11温湿度读取 4.5、PWM配置——光照灯、水泵、风扇 4.6、串口——esp8266模…

【游戏设计原理】96 - 成就感

成就感是玩家体验的核心&#xff0c;它来自完成一件让自己满意的任务&#xff0c;而这种任务通常需要一定的努力和挑战。游戏设计师的目标是通过合理设计任务&#xff0c;不断为玩家提供成就感&#xff0c;保持他们的参与热情。 ARCS行为模式&#xff08;注意力、关联性、自信…

MySQL CTE:解锁SQL查询新模式

目录 一、CTE 初相识 二、CTE 基础语法 &#xff08;一&#xff09;基本语法结构 &#xff08;二&#xff09;语法规则详解 三、非递归 CTE 应用实例 &#xff08;一&#xff09;单 CTE 简单查询 &#xff08;二&#xff09;多 CTE 联合查询 四、递归 CTE 深入探索 &…

C#,入门教程(12)——数组及数组使用的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(11)——枚举&#xff08;Enum&#xff09;的基础知识和高级应用https://blog.csdn.net/beijinghorn/article/details/123917587https://blog.csdn.net/beijinghorn/article/details/123917587 数组是一种数据集合&#xff0c;是一组…

【leetcode练习·二叉树】计算完全二叉树的节点数

本文参考labuladong算法笔记[拓展&#xff1a;如何计算完全二叉树的节点数 | labuladong 的算法笔记] 如果让你数一下一棵普通二叉树有多少个节点&#xff0c;这很简单&#xff0c;只要在二叉树的遍历框架上加一点代码就行了。 但是&#xff0c;力扣第第 222 题「完全二叉树的…