一文上手SpringSecurity【五】

对于前后端不分离的项目,我们可以采用一文上手SpringSecurity【四】当中的方式来自定义用户的登录页面和数据源,数据源目前采用的是模拟的方式来实现的,本篇内容主要介绍一下spring security对于前后端分离项目如何实现认证和授权的.

一、前后端分离的认证面对的问题

1.1 传统的前后端不分离认证特点

  • 传统前后端不分离项目,Spring Security认证通常基于会话(session-based authentication),即用户登录成功后,服务器会在服务器端创建一个用户会话,并生成一个唯一的会话ID(JSESSIONID),然后通过Cookie发送给客户端。客户端的每次请求都会携带这个会话ID,服务器通过该ID在内存中查找用户的会话信息。这种方式的核心在于服务器要维护用户的会话状态,因此属于有状态认证。
  • 从身份认证流程上来说,用户通过浏览器访问服务器渲染的登录页面,提交用户名和密码后,Spring Security会处理表单请求(POST /login)。登录成功后,服务器会自动重定向到一个页面或返回相应的视图(例如首页),整个过程通过HTML表单、会话和页面跳转来完成。服务器不仅处理业务逻辑,还负责渲染页面【采用了模板引擎的项目】。
  • 跨域问题, 由于前端和后端在同一个服务器上运行,通常不会涉及跨域问题
  • 登录和登出的机制, 用户登录后,Spring Security会在服务器端维护会话,用户注销时,后端通过销毁会话来完成登出操作。这个过程通过Spring Security自带的表单登录机制进行。登出后,通常会通过服务器端重定向到登录页面或其他页面。
  • CSRF(跨站请求伪造)防护上, Spring Security默认启用了CSRF防护机制。在基于会话的认证中,服务器通过生成CSRF token并将其嵌入到HTML表单中,来防止CSRF攻击。当用户提交表单时,服务器验证CSRF token是否正确。
  • 登录成功或失败后,服务器通常会返回一个完整的HTML页面(或通过重定向实现),用户可以看到对应的视图。所有页面跳转和导航由后端控制,通过服务器端渲染实现页面切换.
  • 用户信息存储去传递, 用户信息通常存储在服务器的会话中,浏览器的每次请求都会自动携带会话ID,通过该ID服务器可以找到用户的身份信息。
    1

1.2 现代的前后端分离认证特点

  • 在前后端分离的项目中,通常使用JWT(JSON Web Token)或其他Token-based认证(如OAuth2)。用户登录成功后,服务器会生成一个Token(通常是JWT),客户端在每次请求时将Token放入HTTP请求头中(如Authorization: Bearer ),然后服务器通过解析Token来验证用户身份。这种方式不依赖于服务器的会话机制,服务器不会存储用户的状态信息(无状态认证),因此更适合前后端分离的场景。
  • 在前后端分离项目中,前端与后端之间通过API进行交互。用户提交用户名和密码时,通常会通过Ajax调用一个API端点(例如POST /api/login),Spring Security在后端验证后返回一个Token(例如JWT)。
    • 客户端(通常是单页应用,如React或Vue.js)会将Token保存在浏览器的localStorage或sessionStorage中,并在后续的请求中将其附加到HTTP头部。后端API通过验证Token来识别用户。
    • 前后端分离的项目通常不会依赖于服务器端的页面重定向,而是由前端框架自行控制页面跳转。
  • 前后端分离项目中,前端和后端通常运行在不同的域名或端口下,导致浏览器的同源策略限制。为了允许跨域请求,必须配置CORS(Cross-Origin Resource Sharing)策略。Spring Security需要通过配置允许特定的域名进行跨域访问,尤其是登录和获取资源的请求。
  • 用户登录后,Token会被保存在客户端(例如localStorage或sessionStorage)。登出时,客户端只需要删除存储的Token,并通知后端(如果需要),可以通过API让后端使Token失效(如Token黑名单)或删除服务器端的相关记录(如刷新Token)。
  • 由于Token-based认证(如JWT)使用的是无状态的HTTP头部认证,不依赖于Cookie和会话,因此通常不需要CSRF防护。可以通过禁用Spring Security的CSRF防护(http.csrf().disable())来适配前后端分离的项目。
  • 登录成功后,后端不会返回HTML页面,而是返回一个Token(例如JWT)或JSON格式的用户信息,前端通过处理API返回的结果进行页面的跳转和状态管理。
    • 所有的页面跳转和视图渲染由前端框架(如React、Vue、Angular)处理,后端只负责返回数据而不关心页面渲染。
  • 用户信息通常通过Token(如JWT)在客户端存储。Token中包含了用户的身份信息(如sub,exp等字段),后端通过解析Token来验证用户身份。Token无需存储在服务器,客户端携带Token的每次请求可以在无状态下进行身份认证。

2

1.3 前后端分离认证需要的准备工作

  • 前端工作, 采用vue3进行开发一个简单的页面
  • 认证凭证JWT,这里不做详细介绍,直接使用,默认已经熟悉
  • 跨域处理,直接在后端配置即可
  • 自定义认证流程逻辑编写
  • 测试

二、前端端分离认证实操

2.1 前端工程准备

  • 创建vue3 工程,别太复杂了.够用就行了.
  • 引入路由组件、Axios、Element Plus 按照官方文档配置
  • 相应的工程目录如下所示
    参考
    一共两个路由组件,登录和主页.效果展示:
    login
    目前没有登录逻辑,点击登录,直接进入主页,之后会在这里进行登录的认证请求.
    home
    具体内容填充,之后RBAC的时候再填充相应的内容.

2.2 搭建后端工程

  • JDK17
  • Spring boot 3.3.4

2.2.1 引入JWT工具类

关于jwt自行度娘之,这里jwt核心的作用就是: 当服务器认证完客户端之后, 发给客户端存储的用户凭证,认证通过之后,客户端的每次请求都要携带这个凭证

引入jwt需要的依赖,这里要注意,由于我们使用的是JDK 17,所以必须得引入JWT兼容高版本的依赖.

<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt-api</artifactId>
   <version>0.11.2</version>
</dependency>
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt-impl</artifactId>
   <version>0.11.2</version>
   <scope>runtime</scope>
</dependency>
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
   <version>0.11.2</version>
   <scope>runtime</scope>
</dependency>
<!--解决高版本JDK问题-->
<!--javax.xml.bind.DatatypeConverter错误-->
<dependency>
   <groupId>javax.xml.bind</groupId>
   <artifactId>jaxb-api</artifactId>
   <version>2.3.0</version>
</dependency>
<dependency>
   <groupId>com.sun.xml.bind</groupId>
   <artifactId>jaxb-impl</artifactId>
   <version>2.3.0</version>
</dependency>
<dependency>
   <groupId>com.sun.xml.bind</groupId>
   <artifactId>jaxb-core</artifactId>
   <version>2.3.0</version>
</dependency>
<dependency>
   <groupId>javax.activation</groupId>
   <artifactId>activation</artifactId>
   <version>1.1.1</version>
</dependency>

JWT工具类封装,你也可以自己找找,实现功能即可.这玩意一找一大大堆

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.UUID;

public class JwtUtil {
   
   </
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值