Web-登录功能实现(含JWT令牌)

news2024/12/26 9:22:36

登录功能

这个登陆功能先不返回JWT令牌
在这里插入图片描述
登陆会返回JWT令牌
一会在登陆验证时讲解JWT令牌(返回的data就是它)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

登录校验

概述

就是你比如复制一个url
用一个未曾登陆对应url系统的浏览器访问
他会先进入登陆页面
登陆校验就是实现这个功能
简而言之,就是不能让你直接访问内部数据,要先登陆才可以

首先http协议是无状态的
每次请求都是独立的
而我们浏览器和web服务器之间就是http协议
在这里插入图片描述
实现思路
存一个登陆标记
在这里插入图片描述
每个请求前有if判断对应队列标记
登陆就正常执行,没有登陆就去登陆界面
但是:这样太繁琐了
在这里插入图片描述
所以我们使用统一拦截来做
在这里插入图片描述

对应技术主要介绍登陆标记(会话技术)和统一拦截呗
在这里插入图片描述

会话技术

在这里插入图片描述
简而言之会话跟踪技术就是保证同一浏览器多个http请求之间能够数据共享
一个会话可包含多个请求(这些请求之间数据共享)
共享数据作用
比如你更新验证码是一次请求,然后它是不是返回了结果
然后你输入验证码登录,又是一次请求
他需要验证你输入和上一次请求返回的数据是否相同
so:需要请求之间的数据共享
在这里插入图片描述
会话跟踪就是保证数据共享的核心技术
有三种实现方式
1.客户端Cookie
2.服务器端session
3.令牌技术(最常用)

会话跟踪技术-Cookie

cookie
优点:http协议支持的
当你进行请求的时候,如果服务端设置cookie
会自动将cookie以及里面数据返回给浏览器-响应头
然后浏览器会自动存储该cookie
下次请求的时候会携带该cookie进行访问-请求头
缺点:移动端和ios端不支持
不安全:因为数据存储在浏览器,不能涉及一些隐私数据
cookie不能跨域:因为现在一般是前后端分离部署
你要访问前端页面,返回给你的cookie是不能在访问后端时候用的(或者说是不识别的)
在这里插入图片描述

先访问c1
再访问c2
看看能不能进行数据的同步
在这里插入图片描述
如果响应头有set-cookie这个,浏览器会自动存储起来(因为我们设置了cookie,这是http协议支持的)
在这里插入图片描述
存储在这里
在这里插入图片描述
现在我们访问c2,会发现请求头带着set-cookie(我们原来接收到的cookie)来进行访问
在这里插入图片描述

会话跟踪技术-session

底层:
session底层用cookie实现的
当浏览器请求服务端,服务端建立一个session,每一个session有自己的id
然后服务器端响应数据的时候会将session的id通过cookie响应给浏览器
然后浏览器存储该session的id,每次请求带着这个session的id进行请求
相当于session的id把set-Cookie在响应头和请求头的位置占了
只不过换到了服务器端存储
就可以通过session对象来实现请求数据间的共享
优点就不说了
缺点:底层是cookie的方式,所以cookie的缺点有
而且现在一般是部署多台服务器,如果你第一次请求服务器转载给了1号服务器
而第二次转请求带着对应id到了2号服务器,他就识别不到对应的session,即使识别到了也是错误的

在这里插入图片描述

还是测试一下
s1和s2两个请求,一个session
在这里插入图片描述
s1请求,响应头有session的id,然后浏览器对应的session的ID存储起来
在这里插入图片描述
s2请求,带着session的id到请求头的set-cookie进行请求,且可以获取到s1的数据
在这里插入图片描述

会话跟踪技术-令牌

这种就是请求生成令牌
令牌再反给浏览器,浏览器存储令牌==(令牌存储在浏览器(客户端)中)==
(可以存储在cookie或者别的储存空间)
浏览器带着令牌进行访问再通过拦截判断令牌有效性
想要共享数据把对应数据存储在令牌中即可

1.由于可以存储在任何存储空间不止set-cookie
所以就可以在pc端移动端都可以用
2.服务器端不需要存储数据,就是服务器端是集群(分布式)
也可以使用,且不存储数据在服务器端,减轻服务器端压力
3.不用担心令牌伪造问题,具体在令牌技术讲解

在这里插入图片描述
下面讲常用令牌技术JWT令牌

JWT令牌技术

介绍

三部分之间用.隔开
前两部分是json形式存储后经过Base64编码成的字符串
最后一部分签名是自动生成的根据前两部分(比如第一部分签名算法)并且加入指定秘钥(不是编码)
第一部分是令牌类型和签名算法
第二部分是我们的自定义信息和一些默认信息
在这里插入图片描述
应用场景:登录认证
在这里插入图片描述
就两部操作其实生成令牌和校验令牌

生成令牌和校验令牌

导入依赖,使用对应的工具类Jwts
setExpiration()是设置有效期,单位是毫秒
signWith()设置签名算法和秘钥
setClaim()是设置自定义数据即json

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

对应的生成
在这里插入图片描述
编码当然可以阶码,可以复制该数据到JWT官网即可解码(或者Base64解码工具)解码前两部分
上面是签名算法,你用什么算法生成的选择什么就行
在这里插入图片描述
如何基于Java代码校验JWT令牌
指定签名秘钥和对应字符串即可解析(当然令牌过期、秘钥不对或者字符串不对会报错)
so只要没有报错就是校验成功
在这里插入图片描述
结果如图
在这里插入图片描述

下发和生成JWT令牌功能实现

看开发文档
返回JWT令牌
还说明了对应请求头名(这个是前端做的)
我们只需要生成对应令牌返回给前端(Result里面的data)

在这里插入图片描述
引入一个JWT工具类(自己定义的)
两个方法
1.生成令牌2.校验令牌
指定两个属性

private static String signKey="ieheima";//秘钥是itheima
private static Long exprie=43200000L;//过期时间12个小时

在这里插入图片描述
只需要改controller(因为只有controller是真正接收对应请求和客户端互动的)
controller
发送正确username和password会返回JWT令牌
在这里插入图片描述
前后端联调一下
登录完后的响应令牌

在这里插入图片描述
前端将对应的数据存储在浏览器本地存储空间Local Storage
在这里插入图片描述
然后下次请求就会带着这个JWT令牌
如图一个新请求也会携带该令牌
在这里插入图片描述

统一拦截,校验令牌

就是对应的拦截器了
这里就写两个目前企业常用的
一个Filter一个Interceptor

过滤器Filter

快速入门

就是先过滤一遍
然后从数据库取到数据还能再过滤一遍
就是要经过两次Filter
在这里插入图片描述

快速入门
1.定义一个类实现Filter接口和对应方法,上面写上注解@WebFilter(“”)来表明要拦截上面请求
这里的话是/*就是所有请求都拦截
2.在启动类上加上注解@ServletComponentScan
因为Filter属于JavaWeb组件不是SpringBoot提供的
在这里插入图片描述
注意:是java.servlet包里的Filter接口
接口中就三个方法,初始化,拦截,和销毁
初始化和销毁是有默认实现的,因为不常用
这里就全实现了
在这里插入图片描述

拦截请求中需要进行放行操作
放行需要调用参数chain里面的doFilter()方法,里面参数就是请求和响应

chain.doFilter(request,response);

详解

在这里插入图片描述

Filter执行流程
经过两次Filter,但其实一次请求对应那个方法只会生效一次
就是你放行完执行完对应的controller
会直接到那个方法的下一步操作
也就是放行后逻辑
在这里插入图片描述
拦截路径
注解WebFilter对应的urlPattern属性赋值
在这里插入图片描述
没什么好说的
过滤器链
其实这个doFilter参数就有一个过滤器链
就是需要经过多个过滤器
如果还有过滤器就会放行给下一个过滤器
如果没有就会到放行到web资源
在这里插入图片描述
如果不指定过滤器顺序,默认按首字母排序
在这里插入图片描述

Filter实现登录校验

在这里插入图片描述
在这里插入图片描述
对应的代码逻辑,稍微有点复杂
可以看看
这里因为要返回一个json的数据格式
需要用到albb的fastJson依赖,记得添加

@Slf4j
//@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if(url.contains("login")){
            log.info("登录操作, 放行...");
            chain.doFilter(request,response);
            return;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //6.放行。
        log.info("令牌合法, 放行");
        chain.doFilter(request, response);

    }
}

在这里插入图片描述

拦截器Interceptor

快速入门

在这里插入图片描述
1.定义一个类实现拦截器接口HandlerInterceptor,实现对应方法
2.配置拦截器,定义一个类实现WebMVCConfigurer,且用@Configuration注解
表示是配置类
重写addInterceptor方法注册拦截器到我们之前实现的类
和指定对应拦截路径

在这里插入图片描述
注意:
preHandle的controller执行前的操作
postHandle是controller执行后的操作
afterCompletion是渲染完最后的操作

详解

拦截路径
在这里插入图片描述
根据对应需求在配置文件注册拦截器的时候进行拦截路径的配置
既能指定对于拦截路径,也能指定不拦截的路径

/*只能匹配一级路径,而/**可以匹配任意级路径
如/emp/*能匹配/emp/1但不能匹配/emp/1/2,而emp/*无论后面有多少级路径都可以匹配

执行流程
先过滤器再拦截器
在这里插入图片描述

拦截器实现登录校验

实现思路是一样的
在这里插入图片描述
对应的拦截逻辑

@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override //目标资源方法运行前运行, 返回true: 放行, 放回false, 不放行
    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
        //1.获取请求url。
        String url = req.getRequestURL().toString();
        log.info("请求的url: {}",url);

        //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
        if(url.contains("login")){
            log.info("登录操作, 放行...");
            return true;
        }

        //3.获取请求头中的令牌(token)。
        String jwt = req.getHeader("token");

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
        if(!StringUtils.hasLength(jwt)){
            log.info("请求头token为空,返回未登录的信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)。
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            log.info("解析令牌失败, 返回未登录错误信息");
            Result error = Result.error("NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return false;
        }

        //6.放行。
        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...");
    }
}

当然我们还有对应的配置类进行拦截器注册
在这里插入图片描述

ok

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

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

相关文章

基于EasyExcel的单元格合并自定义算法处理

基于EasyExcel导出Excel后,通过对合并单元格的简单规则配置,实现如下图所示的单元格合并效果: 效果截图 原表格数据如下: 通过配置单元格合并规则后,生成的合并后的表格如下: 注:其中第三列&a…

Android Studio连接安卓手机

1. 创建项目 2. 下载Google USB Driver 点击右上角红框的【SDK Manager】->【SDK Tools】。 也可以在 【tools】->【SDK Manager】->【SDK Tools】下进入。 点击Google USB Driver,下载后点ok。 3. 环境变量 右键【我的电脑】->【高级系统设置】-&g…

基于微信小程序的高校新生自助报道系统设计与实现(Java+spring boot+MySQL+小程序)

获取源码或者论文请私信博主 演示视频: 基于微信小程序的高校新生自助报道系统设计与实现(Javaspring bootMySQL微信小程序) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1…

123、仿真-基于51单片机的电流控制仿真系统设计(Proteus仿真+程序+原理图+参考论文+配套资料等)

方案选择 单片机的选择 方案一:STM32系列单片机控制,该型号单片机为LQFP44封装,内部资源足够用于本次设计。STM32F103系列芯片最高工作频率可达72MHZ,在存储器的01等等待周期仿真时可达到1.25Mip/MHZ(Dhrystone2.1)。内部128k字节…

java报错- 类文件具有错误的版本 61.0, 应为 52.0 请删除该文件或确保该文件位于正确的类路径子目录中。

SpringBoot使用了3.0或者3.0以上,因为Spring官方发布从Spring6以及SprinBoot3.0开始最低支持JDK17,所以仅需将SpringBoot版本降低为3.0以下即可。

ES6类-继承-Symbol-模版字符串

目录 类 继承 ES5 如何继承 ES6继承 Symbol 用途 可以产生唯一的值,独一无二的值 解决命名冲突 getOwnPropertySymbols() 作为全局注册表 缓存 Symbol.for() 消除魔术字符串 模版字符串 类 在javascript语言中,生成实例对象使用构造函数&#xf…

数据库基本操作-----数据库用户管理和授权

目录 一、数据库用户管理 1.新建用户 2.查看用户信息 3.重命名用户 4.删除用户 ​编辑5.修改当前登录用户密码 6.修改其他用户密码 7.忘记 root 密码的解决办法 (1)修…

Redis数据类型 — List

List 列表是简单的字符串列表,按照插入顺序排序,可以从头部或尾部向 List 列表添加元素。 List内部实现 List 类型的底层数据结构是由双向链表或压缩列表实现的: 如果列表的元素个数小于 512 个(默认值,可由 list-m…

详解Single-Shot Alignment Network (S2A-Net) 基于遥感图像的特征对齐旋转目标检测

引言 目标检测:把图像中的物体使用方框标记起来,不同类别物体应使用不同颜色 目标检测其实是寻找物体边界框(bounding box)回归问题(regression)和对物体分类问题(classification)的统一 遥感目标检测:普通的目标检测是日常生活中的横向的图…

2.4 线性表的插入删除

1. 链表的插入删除 1. 单链表插入删除 图1. 单链表插入结点 图2. 单链表删除结点 #include <iostream>typedef struct LNode {int data;struct LNode* next; }LNode;/// <summary> /// 判断链表是否非空 /// </summary> /// <param name"p">…

常见关于数组的函数的介绍

关于字符串函数的介绍 求字符串长度 strlen函数 用于计算字符串的长度的函数&#xff0c;需要使用的库函数是string.h 函数声明 size_t strlen(const char *str)函数模拟实现 #include<stdio.h> #include<assert.h> size_t my_strlen(const char* arr) {asse…

review回文子串

给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 class Solution {List<List<String>> lists new ArrayList<>(); // 用于存储所有可能…

阿里瓴羊One推出背后,零售企业迎数字化新解

配图来自Canva可画 近年来随着数字经济的高速发展&#xff0c;各式各样的SaaS应用服务更是层出不穷&#xff0c;但本质上SaaS大多局限于单一业务流层面&#xff0c;对用户核心关切的增长问题等则没有提供更好的解法。在SaaS赛道日渐拥挤、企业增长焦虑愈演愈烈之下&#xff0c…

Midjourney助力交互设计师设计网站主页

Midjourney的一大核心优势是提供创意设计&#xff0c;这个功能也可以用在网站主页设计上&#xff0c;使用Midjourney prompt 应尽量简单&#xff0c;只需要以"web design for..." or "modern web design for..."开头即可 比如设计一个通用SAAS服务的初创企…

单片机第一季:零基础5——LED点阵

1&#xff0c;第八章-LED点阵 如何驱动LED点阵&#xff1a; (1)单片机端口直接驱动。要驱动8*8的点阵需要2个IO端口&#xff08;16个IO口&#xff09;、要驱动16*16的点阵需要4个IO端口&#xff08;32个IO口&#xff09;。 (2)使用串转并移位锁存器驱动。要驱动16*16点阵只需要…

Linux 系统编程-开发环境(二)

目录 7 压缩包管理 7.1 tar 7.2 rar 7.3 zip 8 进程管理 8.1 who 8.2 ps 8.3 jobs 8.4 fg 8.5 bg 8.6 kill 8.7 env 8.8 top 9 用户管理 9.1 创建用户 9.2 设置用户组 9.3 设置密码 9.4 切换用户 9.5 root用户 9.6 删除用户 10 网络管理 10.1 i…

MySQL-分库分表详解(七)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

【熬夜送书 | 第二期】清华社赞助 | 《前端系列丛书》

前端是什么? 前端&#xff08;Front-End&#xff09;&#xff0c;又称浏览器端、客户端等&#xff0c;是指 Web 应用程序中负责用户交互、界面展示和数据展示的部分。前端技术体系主要包括 HTML、CSS 和 JavaScript 等内容。 其中&#xff0c;HTML&#xff08;Hypertext Mar…

❀如何获得铁粉❀

文章目录 引言一、提供独特的价值1.1 分享专业知识和经验1.2 提供独特的产品或服务1.3 展示个人风格和个性 二、构建真实的关系2.1 回应评论和互动2.2 分享个人故事和经历2.3 建立信任和互信关系 三、提供独家福利3.1 提供折扣和促销3.2 推出限量版产品或服务3.3 独家活动和会员…

位运算常见算法题

文章目录 前言191. 位1的个数338. 比特位计数461. 汉明距离136. 只出现一次的数字260. 只出现一次的数字 III面试题 01.01. 判定字符是否唯一268. 丢失的数字371. 两整数之和137. 只出现一次的数字 II面试题 17.19. 消失的两个数字 前言 本篇文章会涉及多道位运算题目&#xf…