后端登录校验

文章目录

  • 登录校验
    • Cookie
    • Session
    • JWT
      • 生成JWT
      • 校验JWT
      • 基于JWT进行身份验证
      • CSRF
    • Cookie、Session、Token的区别?
    • 过滤器(Filter)
      • 配置过滤器
      • 过滤器链


登录校验

由于HTTP协议是无状态的,我们在进行登录后等一系列接口请求是无法直接区分是哪一个用户的发给服务器的请求,就需要用到会话技术来区分不同用户的请求,也可用来进行登录的校验(统一拦截),传统的会话技术有Cookie、Session,还有目前主流的Token。

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开,会话结束。一次会话可以包含多次请求和响应。

Cookie

Cookie是HTTP支持的一种本地存储的机制,Cookie存放在客户端(浏览器),Cookie的值是一个字符串一般由程序员自己定义。当用户使用浏览器首次访问服务器的时候,响应头中就会带有一个Set-Cookie,这个Cookie的值就会被保存到浏览器中,后面用户的每一次请求都会带上这个Cookie。

在这里插入图片描述

由于Cookie存储空间有限(取决于浏览器具体的实现的,一般都不很大),因此Cookie一般能保存一些简单的信息,最典型的就是用户身份信息。

Cookie的缺点就是,上诉说的存储空间小,不够安全,因为Cookie是存放在本地浏览器中的,Cookie是可以被用户手动禁用的,移动端APP是无法使用Cookie的。

Session

Session是一种存在服务器上的会话技术,对比Cookie来说Session是相对安全一点的。一般Session是借助Cookie来传递身份标识(SessionID)的。在浏览器第一次访问服务器的时候,同样会通过Set-Cookie来将Session带上,并保存在浏览器的Cookie中,再后面的请求中都会带上这个SessionID,来区分不同浏览器。

而Session的缺点和Cookie类似,而且在分布式场景下会存在Session失效的问题。

禁用Cookie后Session还可以使用吗?

一般SessionId是借助Cookie来传递的,但如果Cookie被禁用了,就不知道直接使用Cookie传递SessionId了,有两种解决方式:

  1. 将SessionId放在每个请求的URL中传递,服务端再解析SessionId
  2. 将SessionId 放在表单中也就是请求体中传递给服务端

JWT

JWT全称JSON Web Token,JWT是一个字符串可以在请求头和响应头中直接传递,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。

JWT由三个部分组成:

  • 第一部分:Header(头),记录了令牌的类型、签名算法等,如:

    {"alg": "HS256","typ": "JWT"
    }
    
  • 第二部分:Payload(有效载荷),携带一些自定义信息,默认信息等,如:

    {"sub": "1234567890","name": "John Doe","iat": 1516239022
    }
    
  • 第三部分:Signature(签名),防止Token被篡改,确保安全性,将header、payload,并加入指定密钥,通过指定签名算法计算而来。

在传递Token的时候,前两部分都会转换成base64格式的字符来进行传递,而第三部分则是通过指定的签名算法计算而来的,并不是base64格式的字符串。三个部分用点号分割,如图。

在这里插入图片描述

而由于数字签名的存在,整个JWT当中任何一个地方被篡改了,在校验的时候就会失败。

JWT的使用场景也是登录,在用户登录成功后生成一个token返回给前端,后续每个请求都会带上这个token。

优点:

  • 支持PC端和移动端
  • 支持跨域,JWT 包含了完整的认证和授权信息
  • 解决集群下的认证问题
  • 减轻服务端存储压力,传统的基于会话的认证机制需要服务器在会话中存储用户的状态信息,包括用户的登录状态、权限等。而使用 JWT,服务器无需存储任何会话状态信息,所有的认证和授权信息都包含在 JWT 中

缺点:

需要自己实现

生成JWT

引入依赖

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>
@Test
public void testGenerateJwt() {Map<String,Object> claims = new HashMap<>();claims.put("id",1);claims.put("username","hhy");String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256,"testToken")// 签名算法和签名密钥.setClaims(claims) // 自定义内容.setExpiration(new Date(System.currentTimeMillis() + 3600*1000))// 设置token有效时间为1h.compact();System.out.println(jwt);
}

校验JWT

@Test
public void testParseJwt() {Claims claims = Jwts.parser().setSigningKey("testToken") // 指定签名密钥.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNzA1ODA5NzQyLCJ1c2VybmFtZSI6ImhoeSJ9." +"-XMvQ0q0j7Ew49RZkae3Z0DpZ-a6d4O6Uw9sOi5ft-U")// 解析token.getBody();System.out.println(claims);
}

基于JWT进行身份验证

服务器通过 Payload、Header 和 Secret(密钥)创建 JWT 并将 JWT 发送给客户端。客户端接收到 JWT 之后,会将其保存在 Cookie 或者 localStorage 里面,以后客户端发出的所有请求都会携带这个令牌。而服务端收到这个JWT后就会先进行校验

CSRF

什么 Cookie 无法防止 CSRF 攻击,而 Token 可以?CSRF(Cross Site Request Forgery) 一般被翻译为 跨站请求伪造 。那么什么是 跨站请求伪造 呢?攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

  • 用户登录了网站a.com,并在Cookie中保存了SessionId
  • 接着黑客在test.com网站放置了诱导用户点击的链接,让用户访问了test.com
  • 而访问test.com的时候就会默认带上用户的登录后的SessionId
  • 这时用户访问黑客的页面,就让黑客拿到了用户的SessionId
  • 黑客就可以通过SessionId去伪造用户的请求给a.com发送请求

需要注意的是:黑客无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息

使用Token就可以防止CSRF,在我们登录成功后获得Token之后,一般会将这个Token存放在localStorage中,接着前端通过某些方式给每个发到后端的请求都加上这个Token,即使你用户点击了非法的链接发送请求到服务器,这个请求是不会携带Token的,所有这个请求是非法的。所以要想避免CSRF就可以使用Token,并将Token存储到本地存储中,而不是存储到Cookie中

Cookie、Session、Token的区别?

  1. 首先就是存储位置,Cookie是存储在浏览器的,而Session是存储在服务器上的,Token一般是以加密的方式存储在localStorage 中的
  2. Session一般是配合Cookie来进行使用的,通过响应头中的Set-Cookie来设置一个SessionId,这个Session一般保存在浏览器的Cookie中
  3. Session和Cookie默认是不能跨域的,而Token是可以跨域的,
  4. 因为Cookie是直接存储在浏览器中,所以不适合存储敏感数据,而Session存储在服务器中,相对来说更可靠一些,而Token是以指定的签名算法来进行加密后存储到浏览器中的

过滤器(Filter)

Filter过滤器,是JavaWeb三大组件之一(Servlet、Fiter、Listener)

过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。

过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

配置过滤器

使用步骤:

  1. 定义Filter:定义一个类,实现Filter接口,并重写其方法

  2. 配置Filter:Filter类上加上@WebFilter注解,配置拦截资源的路径。

    @WebFilter(urlPatterns = "/*") // 拦截所有请求
    public class MyFilter implements Filter {/*** 初始化执行一次* @param filterConfig* @throws ServletException*/@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 拦截到请求时,调用该方法,可以调用多次//放行前逻辑filterChain.doFilter(servletRequest,servletResponse);// 放行// 放行后逻辑}@Overridepublic void destroy() {// 销毁方法,服务器关闭时调用,值调用一次}
    }
    

    urlPatterns的值:

    • 拦截具体路径 /login
    • 目录拦截 /user/*
    • 拦截所有 /*
  3. 在启动类上加@ServletComponentScan开启Servlet组件支持,因为Filter是JavaWeb的组件,而不是Spring的

@ServletComponentScan
@SpringBootApplication
public class JwtApplication {public static void main(String[] args) {SpringApplication.run(JwtApplication.class, args);}
}

过滤器链

如果在项目中配置多个过滤器就形成了一个过滤器链,这些过滤器的执行顺序就是按照以类名按照字符串排序执行

在这里插入图片描述


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

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

相关文章

洗地机实用吗?旗舰洗地机品牌实测

在快节奏的生活中&#xff0c;拖地这项繁琐但又必不可少的家务总会在无形中增添我们的压力。喧嚣繁杂的城市生活、无尽的工作似乎已经占据了我们大部分的时间&#xff0c;回到家后还需要一把抹布一桶水开始无休止的的地板清洗&#xff0c;实在疲惫不堪。然而&#xff0c;科技的…

灵活应对:策略模式在软件设计中的应用

策略模式是一种行为型设计模式&#xff0c;它允许定义一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以互换使用。策略模式让算法的变化独立于使用算法的客户端&#xff0c;使得在不修改原有代码的情况下切换或扩展新的算法成为可能。 使用策略模式的场景包…

Vivado Tri-MAC IP的例化配置(三速以太网IP)

目录 1 Tri-MAC IP使用RGMII接口的例化配置1.1 Data Rate1.2 interface配置1.3 Shared Logic配置1.4 Features 2 配置完成IP例化视图 1 Tri-MAC IP使用RGMII接口的例化配置 在网络设计中&#xff0c;使用的IP核一般为三速以太网IP核&#xff0c;使用时在大多数场景下为配置为三…

MaxKey 单点登录认证系统——前端后端合并步骤

开发指南 | MaxKey单点登录认证系统 该项目前端是Angular项目&#xff0c;后端是springboot项目 以maxkey-web-app前后端合并为例 构建MaxKey统一认证前端 maxkey-web-frontend/maxkey-web-app ng build --prod --base-href /sign/static/以上sign由以下得来&#xff1a; 根…

Spark Shuffle Service简介与测试

一 Dynamic Resource Allocation(动态资源分配) 了解Shuffle Service之前&#xff0c;我们需要先了解和Shuffle Service有关的另一个特性&#xff1a;动态资源分配。 Spark管理资源有两种方式&#xff1a;静态资源分配和动态资源分配。 静态资源分配&#xff1a;spark提交任…

esp8266 步骤

安装驱动 http://arduino.esp8266.com/stable/package_esp8266com_index.json oled库 esp8266-oled-ssd1306

远程桌面时连接不上远程计算机是什么问题

在服务器上搭建网络程序时&#xff0c;我们经常会有需要远程连接上服务器进行相关操作&#xff0c;有些用户在远程桌面的时候&#xff0c;有时会有遇上无法连接到远程计算机的情况。 很多用户都曾遇到在远程桌面时出现“未启用对服务器的远程访问”、“远程计算机已关闭”、“…

Unix时间戳详解

前言 Unix时间戳最早是在Unix系统中使用的&#xff0c;之后很多由Unix演变而来的系统也都继承了Unix时间戳的规定。目前&#xff0c;Linux、Windows、安卓这些系统的底层计时系统都使用的是Unix时间戳。 一、Unix时间戳简介 Unix时间戳&#xff08;Unix timestamp&#xff0…

深度学习介绍

对于具备完善业务逻辑的任务&#xff0c;大多数情况下&#xff0c;正常的人都可以给出一个符合业务逻辑的应用程序。但是对于一些包含超过人类所能考虑到的逻辑的任务&#xff0c;例如面对如下任务&#xff1a; 编写一个应用程序&#xff0c;接受地理信息、卫星图像和一些历史…

vscode安装后无右键进入

vscode安装后无右键进入 注&#xff1a;安装时&#xff0c;勾选这两项及可

彻底学会系列:一、机器学习之线性回归

1.基本概念 线性回归&#xff1a; 有监督学习的一种算法。主要关注多个因变量和一个目标变量之间的关系。 因变量&#xff1a; 影响目标变量的因素&#xff1a; X 1 , X 2 . . . X_1, X_2... X1​,X2​... &#xff0c;连续值或离散值。 目标变量&#xff1a; 需要预测的值: t…

Sklearn、TensorFlow 与 Keras 机器学习实用指南第三版(二)

原文&#xff1a;Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第三章&#xff1a;分类 在第一章中&#xff0c;我提到最常见的监督学习任务是回归&#xff08;预测值&#xff09;和分类&#…