Security 的 Session 与 Token 管理
# Security 的 Session 与 Token 管理
前言
在 Web 应用中,用户的身份认证和会话管理是保障系统安全的核心部分。Spring Security 提供了多种方式来管理 Session、保护 CSRF 攻击以及实现基于 Token 的无状态认证。
# 1. Session 管理
在默认情况下,Spring Security 通过 Session 管理用户的登录状态。Session 管理包括会话超时处理、并发登录控制、Session 固定攻击防护等。
# 1.1 Session 失效与超时处理
Spring Security 允许你配置会话超时和失效后的处理方式。
代码示例:配置 Session 超时与失效处理
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.invalidSessionUrl("/session-invalid") // 当 Session 失效时,重定向到指定页面
.maximumSessions(1) // 限制每个用户只能有一个会话,防止并发登录
.maxSessionsPreventsLogin(true); // 当达到最大会话数时,禁止新登录
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
重要参数说明:
invalidSessionUrl(String url)
:当 Session 失效时,重定向到指定的页面(如登录页面)。maximumSessions(int maxSessions)
:配置单个用户的最大会话数,通常用于限制并发登录。maxSessionsPreventsLogin(boolean preventsLogin)
:如果设置为true
,当达到最大会话数时,阻止用户再次登录。如果为false
,则允许新的登录,旧的会话会失效。
使用场景: 适用于需要严格控制用户并发登录、以及对 Session 失效进行精细化处理的应用场景。
# 1.2 Session 固定攻击防护
Session 固定攻击(Session Fixation)是一种攻击方式,攻击者通过设置一个固定的 Session ID 来冒充用户。Spring Security 默认会在用户成功登录时重新生成一个新的 Session ID,以防止这种攻击。
代码示例:Session 固定攻击防护配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionFixation().migrateSession(); // 默认配置,用户登录成功后重新生成 Session ID
}
2
3
4
5
6
其他选项:
migrateSession()
:重新生成 Session ID(默认)。newSession()
:创建一个全新的 Session。none()
:不处理 Session ID,保留原有 Session ID(不推荐)。
使用场景: 适用于需要保护用户登录过程免受 Session 固定攻击的应用。
# 2. CSRF 保护
CSRF(跨站请求伪造)是一种常见的 Web 攻击方式,攻击者诱导用户在未授权的情况下执行恶意操作。Spring Security 默认启用了 CSRF 防护,通过生成和验证 CSRF Token 来防止此类攻击。
# 2.1 什么是 CSRF 保护?
CSRF 防护机制通过在每个表单请求中嵌入一个随机生成的 Token,并在服务器端进行验证,确保请求的合法性。如果请求中缺少或包含错误的 CSRF Token,服务器会拒绝该请求。
# 2.2 配置 CSRF 保护
Spring Security 默认开启 CSRF 防护。如果你的应用是 RESTful API,可以选择禁用它,因为 API 通常通过 JWT 或其他无状态方式认证,不依赖 Session。
代码示例:禁用 CSRF 防护(适用于 RESTful API)
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable(); // 禁用 CSRF 防护
}
2
3
4
5
使用场景: 在传统的 Web 应用中,CSRF 防护是必不可少的,尤其是表单提交较多的场景。但在基于 Token 的无状态 API 中,可以安全地禁用 CSRF 防护。
# 3. Token 认证(JWT)
在微服务架构和前后端分离的项目中,Session 认证会带来一定的负担,特别是在无状态服务中,JWT(JSON Web Token)被广泛使用来实现无状态的用户认证。
# 3.1 什么是 JWT?
JWT 是一种轻量级的 Token 格式,包含了用户的认证信息,服务器在认证用户后生成 JWT,并将其返回给客户端,客户端在后续请求中携带该 Token 来进行认证。由于 JWT 是自包含的,因此可以实现无状态的认证。
# 3.2 如何生成与验证 JWT?
生成和验证 JWT 通常使用第三方库,如 jjwt
。以下是一个简单的 JWT 生成与验证示例:
代码示例:JWT 生成与验证
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtTokenProvider {
private final String jwtSecret = "secretKey"; // 密钥,用于签名 JWT
private final long jwtExpirationMs = 86400000; // Token 有效期(24小时)
// 生成 JWT
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username) // 设置主题为用户名
.setIssuedAt(new Date()) // 设置签发时间
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs)) // 设置过期时间
.signWith(SignatureAlgorithm.HS512, jwtSecret) // 使用 HS512 算法和密钥进行签名
.compact();
}
// 验证 JWT
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false; // 如果验证失败,返回 false
}
}
// 从 JWT 中获取用户名
public String getUsernameFromToken(String token) {
return Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
重要参数说明:
setSubject(String subject)
:设置 JWT 的主体(通常为用户名)。setIssuedAt(Date issuedAt)
:设置 JWT 的签发时间。setExpiration(Date expiration)
:设置 JWT 的过期时间。signWith(SignatureAlgorithm algorithm, String secret)
:使用指定的签名算法和密钥对 JWT 进行签名。
使用场景: 适用于需要无状态认证的场景,如前后端分离的项目或微服务架构,使用 JWT 可以减少服务器的负担并提高系统的可扩展性。
总结
- Session 管理:通过配置 Spring Security 的 Session 管理,可以实现对会话的精细化控制,如并发登录限制、Session 失效处理、Session 固定攻击防护等。
- CSRF 保护:CSRF 是常见的 Web 攻击,Spring Security 默认开启 CSRF 防护。在基于 Token 的无状态应用中可以禁用该防护。
- Token 认证(JWT):JWT 是一种轻量级的无状态认证方式,广泛应用于微服务和前后端分离项目。通过生成和验证 JWT,可以实现用户认证和授权的无状态化。
# 4. JWT 进行 Token 验证 实战
在基于 Spring Security 的应用中,JWT(JSON Web Token)是一种常见的无状态认证方式,特别适用于前后端分离的架构。通过 JWT,可以将用户认证信息保存在 Token 中,而不再依赖传统的 Session,减少了服务器的状态管理压力。
# 1. JWT 认证的基本流程
- 用户登录时,服务器验证用户名和密码,成功后生成 JWT (
同时设置过期时间
),然后将其返回给客户端。 - 客户端在后续请求中携带 JWT(通常放在
Authorization
头部)。 - 服务器在接收到请求后,从请求头中解析 JWT,验证其有效性,并根据 Token 中的信息决定是否允许访问受保护的资源。
# 2. 项目依赖配置
在使用 JWT 时,需要添加一些相关依赖,例如 jjwt
库。
pom.xml
配置:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2
3
4
5
# 3. JWT 工具类的实现
首先,需要一个工具类来生成和验证 JWT。该类负责创建、解析和验证 JWT。
代码示例:JWT 工具类
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtTokenProvider {
// 密钥,用于签名和验证 JWT
private final String jwtSecret = "mySecretKey";
// Token 有效期(单位:毫秒)
private final long jwtExpirationMs = 86400000; // 24小时
// 生成 JWT Token
public String generateToken(String username) {
return Jwts.builder()
.setSubject(username) // 设置主题为用户名
.setIssuedAt(new Date()) // 设置签发时间
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs)) // 设置过期时间
.signWith(SignatureAlgorithm.HS512, jwtSecret) // 使用 HS512 算法和密钥进行签名
.compact();
}
// 从 JWT 中获取用户名
public String getUsernameFromToken(String token) {
return Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody()
.getSubject(); // 从 Claims 中获取用户名
}
// 验证 JWT Token 是否有效
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token);
return true;
} catch (Exception e) {
// 解析失败说明 Token 无效(可能已过期或签名不正确)
return false;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
重要参数说明:
setSubject(String subject)
:设置 JWT 的主体,通常是用户名。setIssuedAt(Date issuedAt)
:设置 JWT 的签发时间。setExpiration(Date expiration)
:设置 JWT 的过期时间。过期后,Token 将不再有效。signWith(SignatureAlgorithm algorithm, String secret)
:使用指定的签名算法和密钥对 JWT 进行签名。常用的算法是HS512
。
# 4. JWT 过滤器的实现
为了在每次请求时验证 Token,需要在 Spring Security 的过滤器链中添加一个自定义过滤器,该过滤器从请求头中提取 JWT,验证其有效性,并将用户信息注入到 Spring Security 的上下文中。
代码示例:JWT 过滤器
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final JwtTokenProvider jwtTokenProvider;
private final UserDetailsService userDetailsService;
public JwtAuthenticationFilter(JwtTokenProvider jwtTokenProvider, UserDetailsService userDetailsService) {
this.jwtTokenProvider = jwtTokenProvider;
this.userDetailsService = userDetailsService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
// 从请求头中获取 Authorization 字段
String authHeader = request.getHeader("Authorization");
String token = null;
String username = null;
// 检查是否包含 Bearer Token
if (authHeader != null && authHeader.startsWith("Bearer ")) {
token = authHeader.substring(7); // 去掉 "Bearer " 前缀
username = jwtTokenProvider.getUsernameFromToken(token);
}
// 验证 Token 并设置认证信息
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
// 验证 Token 是否有效
if (jwtTokenProvider.validateToken(token)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// 将认证信息设置到 Spring Security 的上下文中
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
// 继续过滤器链
chain.doFilter(request, response);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
重要参数说明:
getHeader(String name)
:从请求头中获取指定的字段,这里用于获取Authorization
字段。SecurityContextHolder.getContext().getAuthentication()
:获取当前的认证信息,防止重复认证。UsernamePasswordAuthenticationToken
:Spring Security 的认证对象,包含用户的身份和权限信息。
使用场景: 当需要在每个请求中验证用户身份时,使用自定义过滤器将 JWT 验证逻辑集成到 Spring Security 的认证流程中。
# 5. Spring Security 配置整合 JWT 过滤器
最后,需要将自定义的 JWT 过滤器集成到 Spring Security 的过滤器链中。
代码示例:Spring Security 配置
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
private final MyUserDetailsService myUserDetailsService;
public SecurityConfig(JwtTokenProvider jwtTokenProvider, MyUserDetailsService myUserDetailsService) {
this.jwtTokenProvider = jwtTokenProvider;
this.myUserDetailsService = myUserDetailsService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // 禁用 CSRF,因为我们使用的是无状态的 Token 认证
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 不创建或使用 Session
.and()
.authorizeRequests()
.antMatchers("/login", "/register").permitAll() // 允许所有用户访问登录和注册接口
.anyRequest().authenticated() // 其他请求都需要认证
.and()
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider, myUserDetailsService),
UsernamePasswordAuthenticationFilter.class); // 在 UsernamePasswordAuthenticationFilter 之前添加 JWT 过滤器
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
重要参数说明:
csrf().disable()
:禁用 CSRF 防护,适用于使用 JWT 的无状态认证。sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
:配置为无状态,Spring Security 不再创建或使用 Session。addFilterBefore()
:在指定的过滤器之前添加自定义过滤器,这里在UsernamePasswordAuthenticationFilter
之前添加 JWT 过滤器。
# 6. 用户登录成功后生成 JWT 并返回
当用户登录成功后,服务器需要生成一个 JWT,并将其返回给前端。这个过程通常发生在处理用户登录请求的 Controller 中。以下是一个完整的流程:
- 用户通过前端发送登录请求(包含用户名和密码)。
- 服务器接收请求后,通过 Spring Security 验证用户名和密码。
- 验证成功后,生成 JWT 并将其返回给前端。
代码示例:用户登录并生成 JWT
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenProvider jwtTokenProvider;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
// 进行用户认证
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
// 设置认证信息到上下文中
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成 JWT Token
String jwt = jwtTokenProvider.generateToken(authentication.getName());
// 返回 Token 给前端
return ResponseEntity.ok(new JwtResponse(jwt));
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
关键点说明
authenticationManager.authenticate(...)
:通过用户名和密码进行认证,这是 Spring Security 的默认认证机制。SecurityContextHolder.getContext().setAuthentication(authentication)
:将认证信息保存到 Spring Security 的上下文中。jwtTokenProvider.generateToken(authentication.getName())
:使用之前实现的JwtTokenProvider
类生成 JWT,通常使用用户名作为 Token 的主体。ResponseEntity.ok(new JwtResponse(jwt))
:将生成的 JWT 包装在响应对象中返回给前端。
LoginRequest 类
用于接收前端传递的登录请求:
public class LoginRequest {
private String username;
private String password;
// Getters and setters...
}
2
3
4
5
6
JwtResponse 类
用于包装返回给前端的 JWT:
public class JwtResponse {
private String token;
public JwtResponse(String token) {
this.token = token;
}
// Getters and setters...
}
2
3
4
5
6
7
8
9
总结
通过以上配置,Spring Security 可以无缝支持基于 JWT 的无状态认证。JWT 认证的核心包括:
- Token 的生成与解析:通过工具类生成和解析 JWT,并在请求中验证其有效性。
- 自定义过滤器:在每次请求中通过过滤器验证 JWT,确保用户身份的合法性。
- Spring Security 的整合:通过将 JWT 过滤器集成到 Spring Security 的认证流程中,实现全面的无状态安全管理。
# 5. 前端如何保存和携带 JWT Token
在使用 Spring Security 进行 JWT 认证时,前端(基于 Vue 和 Axios)需要在登录成功后保存 Token,并在每次请求时将 Token 携带在请求头中。本文将详细介绍如何在 Vue 项目中处理 JWT 的保存、获取和携带,包括关键 API 的使用说明和详细代码注释。
# 1. 登录成功后保存 Token
当用户通过登录接口认证成功后,后端会返回一个 JWT。前端需要将这个 Token 保存到本地存储中,通常使用 localStorage
或 sessionStorage
。
代码示例:登录接口调用并保存 Token
// 登录页面中的方法
methods: {
async login() {
try {
const response = await axios.post('/login', {
username: this.username, // 用户输入的用户名
password: this.password // 用户输入的密码
});
// 假设后端返回的数据格式为 { token: 'jwt-token-value' }
const token = response.data.token;
// 将 Token 保存到 localStorage(适用于长期登录)或 sessionStorage(适用于会话级别登录)
localStorage.setItem('jwtToken', token); // 保存 Token 到 localStorage
// 设置 Axios 默认请求头,后续所有请求都会自动携带该 Token
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
// 跳转到主页或其他页面
this.$router.push('/home');
} catch (error) {
console.error('登录失败', error);
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
重要参数说明:
localStorage.setItem('jwtToken', token)
:将 Token 保存到localStorage
中,适用于用户希望在页面刷新或重新打开浏览器时仍然保持登录状态。axios.defaults.headers.common['Authorization'] = 'Bearer ' + token
:设置 Axios 的全局请求头,这样所有后续请求都会自动携带 Token。
使用场景: 适用于用户登录后需要保持会话状态并进行多次请求的场景。
# 2. 在请求中携带 Token
为了确保每次请求都携带 Token,可以通过全局拦截器或在具体请求中手动添加 Authorization
头。
# 2.1 使用 Axios 请求拦截器
通过请求拦截器可以自动为所有请求添加 Authorization
头部。
代码示例:配置 Axios 请求拦截器
// 在 Vue 项目中(如 main.js)配置全局拦截器
axios.interceptors.request.use(
config => {
// 从 localStorage 或 sessionStorage 中获取 Token
const token = localStorage.getItem('jwtToken');
if (token) {
// 在请求头中携带 Token
config.headers['Authorization'] = `Bearer ${token}`;
}
return config; // 返回修改后的配置
},
error => {
return Promise.reject(error);
}
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
重要参数说明:
axios.interceptors.request.use()
:设置请求拦截器,所有请求在发出之前都会经过这个拦截器,用于动态添加或修改请求配置。config.headers['Authorization'] = 'Bearer ' + token
:将 Token 添加到请求头中,确保后端能够识别和验证用户身份。
使用场景: 适用于所有请求都需要携带 JWT Token 的场景。
# 2.2 在单个请求中手动添加 Token
如果不希望所有请求都携带 Token,可以在具体的请求中手动添加 Authorization
头。
代码示例:在单个请求中手动添加 Token
axios.get('/protected-resource', {
headers: {
Authorization: `Bearer ${localStorage.getItem('jwtToken')}`
}
})
.then(response => {
console.log('数据获取成功', response.data);
})
.catch(error => {
console.error('请求失败', error);
});
2
3
4
5
6
7
8
9
10
11
重要说明: 手动添加请求头适合在某些特殊场景下,仅需要在特定请求中携带 Token。
# 3. 处理 Token 过期的情况
Token 通常有有效期,前端需要处理 Token 过期的情况。当后端返回 401(未授权)状态时,可以清除失效的 Token 并重定向到登录页面。
代码示例:处理 401 错误
axios.interceptors.response.use(
response => response, // 如果响应正常,直接返回
error => {
if (error.response.status === 401) {
// 清除过期的 Token
localStorage.removeItem('jwtToken');
// 跳转到登录页面
this.$router.push('/login');
}
return Promise.reject(error); // 返回错误信息
}
);
2
3
4
5
6
7
8
9
10
11
12
重要参数说明:
localStorage.removeItem('jwtToken')
:清除过期的 Token,确保用户重新登录。this.$router.push('/login')
:通过 Vue Router 跳转到登录页面,提示用户重新进行认证。
使用场景: 适用于处理用户登录过期或失效时的场景。
# 4. 通过响应拦截器保存 Token
如果希望在每次登录时自动保存 Token,可以通过 Axios 的响应拦截器实现。
代码示例:通过响应拦截器保存 Token
axios.interceptors.response.use(
response => {
// 判断是否为登录请求,并检查是否包含 token
if (response.config.url === '/login' && response.data.token) {
const token = response.data.token;
// 将 Token 保存到 localStorage
localStorage.setItem('jwtToken', token);
// 设置 Axios 默认请求头,后续所有请求都会携带该 Token
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
}
return response;
},
error => {
// 处理响应错误,例如 401 未授权错误
if (error.response.status === 401) {
localStorage.removeItem('jwtToken');
this.$router.push('/login');
}
return Promise.reject(error);
}
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
适用场景: 当需要在全局自动处理登录响应并保存 Token 时,这种方式更为简洁。
总结
在基于 Vue 和 Axios 的前端应用中,JWT 的管理包括:
- 保存 Token:登录成功后,将 Token 保存到
localStorage
或sessionStorage
中。 - 请求中携带 Token:通过全局拦截器或手动设置请求头,将 Token 添加到
Authorization
头部。 - 处理 Token 过期:通过响应拦截器捕获 401 错误,并执行相应的重定向和清除操作。