# filter
**Repository Path**: zwCeCe/filter
## Basic Information
- **Project Name**: filter
- **Description**: 基于spring boot starter的拦截器
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-07-12
- **Last Updated**: 2025-07-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 用户登录验证系统
## 概述
这是一个基于Spring Boot的用户登录验证系统,通过拦截器实现用户ID和IP地址的双重验证机制。系统采用Redis缓存和数据库双层验证,确保用户访问的安全性。支持配置属性的动态缓存和补偿机制。
## 功能特性
- **ID验证**: 验证用户请求是否携带有效的用户ID
- **IP地址验证**: 验证用户IP地址是否与缓存中的记录一致
- **Redis缓存**: 使用Redis存储用户ID和IP的映射关系,提高验证效率
- **异常记录**: 当IP地址不匹配时,自动记录到数据库用于安全审计
- **灵活配置**: 支持通过配置文件启用/禁用验证功能
- **项目识别**: 支持项目名称标识,便于多项目管理
- **配置缓存**: 自动将配置属性缓存到Redis,支持动态配置更新
- **补偿机制**: 配置缓存失效时自动重新存储,确保系统稳定运行
## 系统架构
### 核心组件
1. **LoginInterceptor**: 主要的拦截器,处理所有的验证逻辑
2. **UserSessionService**: 用户会话服务,处理用户验证和记录创建,包含配置补偿机制
3. **CacheService**: 缓存服务,管理Redis中的用户IP信息和配置属性缓存
4. **LoginProperties**: 配置属性类,支持项目名称识别
5. **IdMapper**: ID表的数据访问层
6. **UserMapper**: User表的数据访问层
### 数据表结构
#### Id表
- `keyId`: 主键
- `id`: 用户ID
- `createTime`: 创建时间
#### User表
- `userId`: 主键
- `id`: 用户ID
- `ip_1`: Redis中存储的IP地址
- `ip_2`: 当前访问的IP地址
- `createTime`: 创建时间
- `updateTime`: 更新时间
## 配置缓存补偿机制
### 补偿机制流程
```
请求进入拦截器 → 尝试从Redis获取配置
↓
配置存在? → 使用Redis配置
↓
配置不存在? → 存储本地配置到Redis → 使用本地配置
```
### 配置缓存结构
- **checkId配置**: `config-properties:{project-name}:checkId` → "true"/"false"
- **checkIp配置**: `config-properties:{project-name}:checkIp` → "true"/"false"
- **缓存特点**: 永不过期,支持动态更新
## 验证逻辑流程
### 第一阶段:预处理(preHandle)
```
请求进入 → 补偿机制获取checkId配置 → 检查是否携带id参数
↓
有id → 放行到下一阶段
↓
无id → 返回错误响应,拒绝访问
```
### 第二阶段:后处理(postHandle)
```mermaid
graph TD
A[接收到id和ip] --> A1[补偿机制获取checkId配置]
A1 --> A2{checkId启用?}
A2 -->|否| Z[直接放行]
A2 -->|是| A3[补偿机制获取checkIp配置]
A3 --> A4{checkIp启用?}
A4 -->|否| Z
A4 -->|是| B{Redis中是否存在该id?}
B -->|存在| C{IP是否一致?}
B -->|不存在| F{Id表中是否存在该id?}
C -->|一致| D[静默通过]
C -->|不一致| E[写入User表
ip1=Redis中的IP
ip2=当前IP
向前端报错]
F -->|存在| G[将id和ip存入Redis
通过验证]
F -->|不存在| H[拒绝访问
向前端报错]
```
## 详细流程说明
### 1. 配置补偿机制
在每次请求时,系统会自动执行配置补偿机制:
1. **获取checkId配置**:
- 先从Redis获取:`config-properties:{project-name}:checkId`
- 如果不存在,自动存储当前配置到Redis
- 返回最终使用的配置值
2. **获取checkIp配置**:
- 先从Redis获取:`config-properties:{project-name}:checkIp`
- 如果不存在,自动存储当前配置到Redis
- 返回最终使用的配置值
### 2. Redis存在用户ID的情况
当Redis中存在用户ID时:
- **IP一致**: 用户使用相同的IP地址访问,验证通过,静默放行
- **IP不一致**: 检测到可能的安全威胁
- 在User表中创建记录,保存原IP(ip1)和当前IP(ip2)
- 向前端返回IP不匹配错误
### 3. Redis不存在用户ID的情况
当Redis中不存在用户ID时,查询Id表:
- **Id表中存在**: 说明是有效用户,首次访问或缓存过期
- 将用户ID和当前IP存入Redis缓存
- 验证通过,正常访问
- **Id表中不存在**: 无效用户ID
- 拒绝访问
- 向前端返回用户不存在错误
## 配置说明
### 快速开始
#### 1. 添加依赖
将此starter添加到您的项目中:
```xml
com.userlogin
user-login-spring-boot-starter
1.0.0
```
#### 2. 配置Redis
确保您的项目中已配置Redis连接:
```xml
org.springframework.boot
spring-boot-starter-data-redis
```
#### 3. 创建数据表
执行以下SQL创建必要的数据表:
```sql
-- Id表:存储有效的用户ID
CREATE TABLE `Id` (
`key_id` INT NOT NULL AUTO_INCREMENT,
`id` varchar(50) NOT NULL COMMENT '用户ID',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`key_id`),
UNIQUE KEY `uk_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户ID白名单表';
-- User表:记录IP不匹配的访问日志
CREATE TABLE `user` (
`user_id` INT NOT NULL AUTO_INCREMENT,
`id` varchar(50) NOT NULL COMMENT '用户ID',
`ip1` varchar(45) DEFAULT NULL COMMENT 'Redis中存储的IP',
`ip2` varchar(45) DEFAULT NULL COMMENT '当前访问的IP',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`user_id`),
KEY `idx_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户访问异常记录表';
```
### application.yml 完整配置示例
```yaml
# Spring Boot 基础配置
spring:
application:
name: your-application-name
# 数据库配置
datasource:
url: jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: your_username
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
# Redis配置
redis:
host: localhost
port: 6379
password: your_redis_password
database: 0
timeout: 3000ms
lettuce:
pool:
max-active: 20
max-idle: 10
min-idle: 0
max-wait: -1ms
# MyBatis Plus配置
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
# 用户登录验证配置
userlogin:
# 项目名称标识
project-name: "sutras"
# 是否启用拦截器
enabled: true
# 是否检测ID参数
check-id: true
# 是否检测IP一致性
check-ip: true
# 存入redis时间(秒)
session-timeout: 5
# Redis key前缀
redis-key-prefix: "ecommerce:user:"
```
### 环境配置建议
#### 开发环境 (application-dev.yml)
```yaml
userlogin:
# 开发环境项目标识
project-name: "sutras"
enabled: true
check-id: true
check-ip: true
redis-key-prefix: "dev:user:"
session-timeout: 5
```
#### 生产环境 (application-prod.yml)
```yaml
userlogin:
# 生产环境项目标识
project-name: "sutras"
enabled: true
check-id: true
check-ip: true
redis-key-prefix: "prod:user:"
session-timeout: 5
```
### 配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| `project-name` | string | "unknown-project" | 项目名称标识,用于缓存配置隔离 |
| `enabled` | boolean | true | 是否启用拦截器 |
| `check-id` | boolean | true | 是否启用用户ID参数验证 |
| `check-ip` | boolean | true | 是否启用IP地址一致性验证 |
| `session-timeout` | int | 5 | 用户IP缓存过期时间(秒) |
| `redis-key-prefix` | string | "pengpeng:sutras:dev:Id:" | Redis中存储用户IP的key前缀 |
### 配置层级关系
- **总开关**:`enabled` - 控制整个拦截器是否生效
- **ID验证**:`check-id` - 控制是否验证请求中的id参数
- **IP验证**:`check-ip` - 控制是否验证IP一致性(只有当`check-id`为true时才生效)
- **项目识别**:`project-name` - 用于配置缓存的key前缀,支持多项目部署
### 验证流程
1. **enabled=false**:直接放行,不进行任何验证
2. **check-id=false**:不验证ID参数,直接放行
3. **check-id=true, check-ip=false**:只验证ID参数存在,不验证IP
4. **check-id=true, check-ip=true**:验证ID参数存在 + IP地址一致性
## 动态配置管理
### 配置更新方法
您可以通过以下方式动态更新配置:
#### 1. 直接修改Redis缓存
```bash
# 禁用checkId验证
redis-cli set "config-properties:my-ecommerce-system:checkId" "false"
# 启用checkIp验证
redis-cli set "config-properties:my-ecommerce-system:checkIp" "true"
```
#### 2. 删除缓存触发补偿
```bash
# 删除配置缓存,下次请求时会自动重新存储
redis-cli del "config-properties:my-ecommerce-system:checkId"
redis-cli del "config-properties:my-ecommerce-system:checkIp"
```
### 配置生效时间
- **立即生效**: 配置更改后,下一个请求立即生效
- **无需重启**: 应用程序无需重启即可应用新配置
- **自动恢复**: 如果Redis中的配置被删除,系统会自动使用本地配置重新存储
## 错误响应
系统通过HTTP响应头返回错误信息:
| 错误类型 | X-Auth-Status | X-Auth-Message |
|---------|---------------|----------------|
| 缺少ID参数 | NO_ID | 缺少id参数,访问被拒绝 |
| IP地址不匹配 | IP_MISMATCH | IP地址不匹配,访问异常 |
| 用户不存在 | USER_NOT_FOUND | 用户ID不存在,请检查您的授权 |
### Redis缓存结构
#### 用户IP缓存
- **Key**: `{redis-key-prefix}{userId}`
- **Value**: IP地址
- **TTL**: 根据`session-timeout`配置的秒数自动过期
#### 配置属性缓存
- **Key**: `config-properties:{project-name}:checkId`
- **Value**: "true" 或 "false"
- **TTL**: 永不过期
- **Key**: `config-properties:{project-name}:checkIp`
- **Value**: "true" 或 "false"
- **TTL**: 永不过期
## 安全特性
1. **多层验证**: 结合Redis缓存和数据库验证,确保系统的可靠性
2. **异常追踪**: 自动记录IP不匹配的访问尝试,便于安全审计
3. **灵活配置**: 可以根据需要启用或禁用特定的验证功能
4. **性能优化**: 优先使用Redis缓存,减少数据库查询压力
5. **项目隔离**: 通过项目名称实现多项目配置隔离
6. **动态配置**: 支持运行时动态调整验证策略
7. **故障恢复**: 配置缓存失效时自动恢复,确保系统稳定性
## 部署说明
1. 确保Redis服务正常运行
2. 配置数据库连接信息
3. **设置唯一的项目名称**: 避免多项目部署时的配置冲突
4. 根据需要调整`application.yml`中的验证配置
5. 启动应用程序
6. **验证配置缓存**: 检查Redis中是否成功存储了配置属性
## 日志监控
系统会记录详细的验证日志:
- 用户ID验证结果
- IP地址匹配情况
- Redis缓存操作
- 数据库查询结果
- 异常访问记录
- 配置补偿机制执行情况
- 配置缓存的读写操作
建议定期检查日志以监控系统安全状态。
## 注意事项
- 确保Redis的TTL配置与`session-timeout`设置一致
- 定期清理User表中的异常访问记录
- 在生产环境中建议启用所有验证功能
- 静态资源请求会被自动排除,不进行验证
- **确保每个项目使用唯一的project-name**,避免配置冲突
- **定期备份Redis中的配置数据**,防止意外丢失
- **监控配置缓存的使用情况**,及时发现异常
## 多项目部署建议
### 项目命名规范
```yaml
# 项目A
userlogin:
project-name: "project-a-prod"
# 项目B
userlogin:
project-name: "project-b-prod"
# 项目C
userlogin:
project-name: "project-c-prod"
```
### 配置隔离验证
部署后可以通过以下方式验证配置隔离:
```bash
# 查看所有配置缓存
redis-cli keys "config-properties:*"
# 应该看到类似以下结果:
# config-properties:project-a-prod:checkId
# config-properties:project-a-prod:checkIp
# config-properties:project-b-prod:checkId
# config-properties:project-b-prod:checkIp
```
---
**版本**: 1.0
**更新时间**: 2025年1月
**新增功能**: 项目识别、配置缓存补偿机制、动态配置管理