96 lines
2.8 KiB
Markdown
96 lines
2.8 KiB
Markdown
# 后端权限配置解决方案
|
||
|
||
## 问题描述
|
||
当前 `/api/users/me` 接口返回 403 Forbidden 错误,原因是 Spring Security 配置中没有明确指定该路径的权限规则。
|
||
|
||
## 解决方案
|
||
|
||
### 方案一:在 SecurityConfig 中添加用户API权限配置(推荐)
|
||
|
||
在 `SecurityConfig.java` 的 `filterChain` 方法中,添加用户相关API的权限配置:
|
||
|
||
```java
|
||
.authorizeHttpRequests(authz -> authz
|
||
// ... 其他配置
|
||
|
||
// 用户相关接口需认证
|
||
.requestMatchers("/api/users/**").authenticated()
|
||
|
||
// 聊天相关接口需认证
|
||
.requestMatchers("/qa/**").authenticated()
|
||
|
||
// 所有其他请求需认证
|
||
.anyRequest().authenticated()
|
||
)
|
||
```
|
||
|
||
### 方案二:实现 /api/users/me 接口
|
||
|
||
在 `UserController.java` 中添加获取当前用户信息的接口:
|
||
|
||
```java
|
||
@GetMapping("/me")
|
||
@Operation(summary = "获取当前用户信息", description = "获取当前登录用户的详细信息")
|
||
@ApiResponse(responseCode = "200", description = "成功获取用户信息")
|
||
public ResponseResult<User> getCurrentUser(Authentication authentication) {
|
||
String username = authentication.getName();
|
||
User user = userMapper.selectOneByUsername(username);
|
||
|
||
if (user == null) {
|
||
return ResponseResult.error("用户不存在");
|
||
}
|
||
|
||
// 隐藏敏感信息
|
||
user.setPassword(null);
|
||
|
||
return ResponseResult.success(user);
|
||
}
|
||
```
|
||
|
||
### 方案三:使用 @PreAuthorize 注解(细粒度控制)
|
||
|
||
如果需要更细粒度的权限控制,可以在控制器方法上使用 @PreAuthorize:
|
||
|
||
```java
|
||
@GetMapping("/me")
|
||
@PreAuthorize("isAuthenticated()")
|
||
public ResponseResult<User> getCurrentUser() {
|
||
// 实现代码
|
||
}
|
||
```
|
||
|
||
## 前端降级方案(已实现)
|
||
|
||
前端已经实现了智能降级方案:
|
||
|
||
1. **首选方案**:调用 `/api/users/me` 获取最新用户信息
|
||
2. **降级方案**:如果接口返回 403 或其他错误,使用本地缓存的用户信息
|
||
3. **用户体验**:提供手动刷新按钮,让用户可以尝试更新信息
|
||
|
||
## 建议步骤
|
||
|
||
1. **短期方案**:先使用方案一,在 SecurityConfig 中配置权限规则
|
||
2. **长期方案**:实现方案二,完善用户信息获取接口
|
||
3. **测试验证**:使用前端测试程序验证接口是否正常工作
|
||
|
||
## 安全考虑
|
||
|
||
1. 确保 `/api/users/me` 只返回当前登录用户的信息
|
||
2. 隐藏敏感字段(如密码、salt等)
|
||
3. 考虑添加响应缓存,减少数据库查询
|
||
4. 记录访问日志,监控异常访问
|
||
|
||
## 测试命令
|
||
|
||
修改后端配置后,可以使用以下命令测试:
|
||
|
||
```bash
|
||
# 获取token(先登录)
|
||
curl -X POST http://localhost:8080/api/auth/login \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"contact":"18362903328","code":"123456"}'
|
||
|
||
# 使用token访问用户信息
|
||
curl -X GET http://localhost:8080/api/users/me \
|
||
-H "Authorization: Bearer YOUR_TOKEN_HERE"
|
||
``` |