@ -1,144 +0,0 @@ | |||
# 小程序登录拦截器分离配置说明 | |||
## 配置目标 | |||
将系统的登录拦截器分成后台管理系统和小程序两个独立的拦截器,实现不同的认证策略。 | |||
## 实现方案 | |||
### 1. 创建小程序专用拦截器 | |||
#### 1.1 新增文件 | |||
- `jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/filters/AppletJwtFilter.java` | |||
#### 1.2 核心特性 | |||
```java | |||
@Override | |||
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { | |||
try { | |||
HttpServletRequest httpRequest = (HttpServletRequest) request; | |||
String requestPath = httpRequest.getServletPath(); | |||
// 只处理以/applet开头的请求 | |||
if (!requestPath.startsWith("/applet")) { | |||
return true; // 不是applet请求,直接放行 | |||
} | |||
// 判断当前路径是不是注解了@IngoreAuth路径,如果是,则放开验证 | |||
if (InMemoryIgnoreAuth.contains(requestPath)) { | |||
return true; | |||
} | |||
executeLogin(request, response); | |||
return true; | |||
} catch (Exception e) { | |||
JwtUtil.responseError(response,401,CommonConstant.TOKEN_IS_INVALID_MSG); | |||
return false; | |||
} | |||
} | |||
``` | |||
### 2. 修改Shiro配置 | |||
#### 2.1 修改文件 | |||
- `jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java` | |||
#### 2.2 配置变更 | |||
```java | |||
// 添加自己的过滤器并且取名为jwt和applet | |||
Map<String, Filter> filterMap = new HashMap<String, Filter>(2); | |||
//如果cloudServer为空 则说明是单体 需要加载跨域配置【微服务跨域切换】 | |||
Object cloudServer = env.getProperty(CommonConstant.CLOUD_SERVER_KEY); | |||
filterMap.put("jwt", new JwtFilter(cloudServer==null)); | |||
filterMap.put("applet", new AppletJwtFilter(cloudServer==null)); | |||
shiroFilterFactoryBean.setFilters(filterMap); | |||
// <!-- 过滤链定义,从上向下顺序执行 | |||
// applet专用过滤器,只处理/applet开头的请求 | |||
filterChainDefinitionMap.put("/applet/**", "applet"); | |||
// 其他请求使用jwt过滤器 | |||
filterChainDefinitionMap.put("/**", "jwt"); | |||
``` | |||
## 拦截器分离效果 | |||
### 1. 后台管理系统拦截器 (JwtFilter) | |||
- **作用范围**:除了`/applet/**`之外的所有请求 | |||
- **认证策略**:标准的JWT Token认证 | |||
- **适用场景**:后台管理系统的所有接口 | |||
### 2. 小程序拦截器 (AppletJwtFilter) | |||
- **作用范围**:只处理`/applet/**`开头的请求 | |||
- **认证策略**: | |||
- 支持`@IgnoreAuth`注解的免登录接口 | |||
- 其他接口需要JWT Token认证 | |||
- **适用场景**:小程序相关的所有接口 | |||
## 配置优势 | |||
### 1. 独立认证策略 | |||
- 后台和小程序可以使用不同的认证方式 | |||
- 可以为小程序配置更宽松的认证策略 | |||
- 支持不同的Token格式和验证逻辑 | |||
### 2. 更好的安全性 | |||
- 小程序接口与后台接口完全隔离 | |||
- 可以针对小程序特点定制安全策略 | |||
- 减少攻击面 | |||
### 3. 便于维护 | |||
- 小程序相关的认证逻辑独立管理 | |||
- 可以独立升级和配置 | |||
- 便于调试和问题排查 | |||
## 使用示例 | |||
### 1. 小程序免登录接口 | |||
```java | |||
@GetMapping("/health") | |||
@IgnoreAuth | |||
@Operation(summary = "健康检查", description = "检查健康管理小程序模块运行状态") | |||
public Result<String> health() { | |||
return Result.OK("健康管理小程序模块运行正常"); | |||
} | |||
``` | |||
### 2. 小程序需要登录的接口 | |||
```java | |||
@GetMapping("/user/info") | |||
@Operation(summary = "获取用户信息", description = "获取小程序用户信息") | |||
public Result<UserInfo> getUserInfo() { | |||
// 需要登录才能访问 | |||
return Result.OK(userInfo); | |||
} | |||
``` | |||
### 3. 后台管理接口 | |||
```java | |||
@GetMapping("/sys/user/list") | |||
@Operation(summary = "用户列表", description = "获取后台用户列表") | |||
public Result<IPage<SysUser>> getUserList() { | |||
// 使用标准的后台认证 | |||
return Result.OK(userList); | |||
} | |||
``` | |||
## 注意事项 | |||
1. **路径匹配顺序**:`/applet/**` 必须在 `/**` 之前配置 | |||
2. **跨域支持**:两个拦截器都支持跨域配置 | |||
3. **多租户支持**:都支持多租户的TenantContext | |||
4. **异步支持**:如果需要异步支持,需要在FilterRegistrationBean中配置 | |||
## 验证方法 | |||
1. **小程序接口**: | |||
- 访问 `/applet/health/health` 应该能正常访问(有@IgnoreAuth注解) | |||
- 访问 `/applet/user/info` 需要Token认证 | |||
2. **后台接口**: | |||
- 访问 `/sys/user/list` 需要Token认证 | |||
- 访问 `/sys/login` 不需要认证(在anon列表中) | |||
3. **Swagger文档**: | |||
- 只显示 `/applet` 开头的接口 | |||
- 文档标题已更新为"小程序API接口文档" |
@ -1,216 +0,0 @@ | |||
# 小程序和后台不同Token配置说明 | |||
## 配置目标 | |||
为小程序和后台管理系统配置不同的Token解析对象,实现独立的认证体系。 | |||
## 实现方案 | |||
### 1. 创建小程序专用Token类 | |||
#### 1.1 新增文件 | |||
- `jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/AppletJwtToken.java` | |||
#### 1.2 核心特性 | |||
```java | |||
public class AppletJwtToken implements AuthenticationToken { | |||
private String token; | |||
public AppletJwtToken(String token) { | |||
this.token = token; | |||
} | |||
@Override | |||
public Object getPrincipal() { | |||
return token; | |||
} | |||
@Override | |||
public Object getCredentials() { | |||
return token; | |||
} | |||
} | |||
``` | |||
### 2. 创建小程序专用Realm | |||
#### 2.1 新增文件 | |||
- `jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/AppletShiroRealm.java` | |||
#### 2.2 核心特性 | |||
```java | |||
@Component | |||
@Slf4j | |||
public class AppletShiroRealm extends AuthorizingRealm { | |||
@Override | |||
public boolean supports(AuthenticationToken token) { | |||
return token instanceof AppletJwtToken; | |||
} | |||
@Override | |||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { | |||
// 小程序专用的身份认证逻辑 | |||
String token = (String) auth.getCredentials(); | |||
LoginUser loginUser = this.checkAppletUserTokenIsEffect(token); | |||
return new SimpleAuthenticationInfo(loginUser, token, getName()); | |||
} | |||
@Override | |||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { | |||
// 小程序专用的权限认证逻辑 | |||
// 可以配置不同的角色和权限体系 | |||
return info; | |||
} | |||
} | |||
``` | |||
### 3. 修改小程序拦截器 | |||
#### 3.1 修改文件 | |||
- `jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/AppletJwtFilter.java` | |||
#### 3.2 配置变更 | |||
```java | |||
@Slf4j | |||
public class AppletJwtFilter extends BasicHttpAuthenticationFilter { | |||
@Resource | |||
private AppletShiroRealm appletRealm; | |||
@Override | |||
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { | |||
// 使用小程序专用的Token和Realm | |||
AppletJwtToken jwtToken = new AppletJwtToken(token); | |||
getSubject(request, response).login(jwtToken); | |||
return true; | |||
} | |||
} | |||
``` | |||
### 4. 配置独立的SecurityManager | |||
#### 4.1 修改文件 | |||
- `jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java` | |||
#### 4.2 配置变更 | |||
```java | |||
@Bean("appletSecurityManager") | |||
public DefaultWebSecurityManager appletSecurityManager(AppletShiroRealm appletRealm) { | |||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); | |||
securityManager.setRealm(appletRealm); | |||
// 配置小程序专用的SecurityManager | |||
return securityManager; | |||
} | |||
``` | |||
## Token解析对象分离效果 | |||
### 1. 后台管理系统Token (JwtToken) | |||
- **Token类**:`JwtToken` | |||
- **Realm**:`ShiroRealm` | |||
- **SecurityManager**:`securityManager` | |||
- **适用场景**:后台管理系统的所有接口 | |||
### 2. 小程序Token (AppletJwtToken) | |||
- **Token类**:`AppletJwtToken` | |||
- **Realm**:`AppletShiroRealm` | |||
- **SecurityManager**:`appletSecurityManager` | |||
- **适用场景**:小程序相关的所有接口 | |||
## 配置优势 | |||
### 1. 独立认证体系 | |||
- 后台和小程序使用不同的Token类 | |||
- 可以配置不同的认证逻辑 | |||
- 支持不同的用户体系和权限模型 | |||
### 2. 更好的安全性 | |||
- 小程序和后台的认证完全隔离 | |||
- 可以针对小程序特点定制安全策略 | |||
- 减少攻击面和风险 | |||
### 3. 便于维护和扩展 | |||
- 小程序相关的认证逻辑独立管理 | |||
- 可以独立升级和配置 | |||
- 便于调试和问题排查 | |||
## 使用示例 | |||
### 1. 小程序接口(使用AppletJwtToken) | |||
```java | |||
@GetMapping("/user/info") | |||
@Operation(summary = "获取小程序用户信息") | |||
public Result<UserInfo> getAppletUserInfo() { | |||
// 使用AppletJwtToken进行认证 | |||
// 通过AppletShiroRealm进行权限验证 | |||
return Result.OK(userInfo); | |||
} | |||
``` | |||
### 2. 后台接口(使用JwtToken) | |||
```java | |||
@GetMapping("/sys/user/list") | |||
@Operation(summary = "获取后台用户列表") | |||
public Result<IPage<SysUser>> getBackendUserList() { | |||
// 使用JwtToken进行认证 | |||
// 通过ShiroRealm进行权限验证 | |||
return Result.OK(userList); | |||
} | |||
``` | |||
### 3. 小程序免登录接口 | |||
```java | |||
@GetMapping("/health") | |||
@IgnoreAuth | |||
@Operation(summary = "健康检查") | |||
public Result<String> health() { | |||
// 使用@IgnoreAuth注解,跳过认证 | |||
return Result.OK("健康管理小程序模块运行正常"); | |||
} | |||
``` | |||
## 拦截器配置 | |||
### 1. 路径匹配规则 | |||
```java | |||
// applet专用过滤器,只处理/applet开头的请求 | |||
filterChainDefinitionMap.put("/applet/**", "applet"); | |||
// 其他请求使用jwt过滤器 | |||
filterChainDefinitionMap.put("/**", "jwt"); | |||
``` | |||
### 2. 过滤器配置 | |||
```java | |||
Map<String, Filter> filterMap = new HashMap<String, Filter>(2); | |||
filterMap.put("jwt", new JwtFilter(cloudServer==null)); | |||
filterMap.put("applet", new AppletJwtFilter(cloudServer==null)); | |||
``` | |||
## 注意事项 | |||
1. **Token类型隔离**:后台使用`JwtToken`,小程序使用`AppletJwtToken` | |||
2. **Realm隔离**:后台使用`ShiroRealm`,小程序使用`AppletShiroRealm` | |||
3. **路径匹配顺序**:`/applet/**` 必须在 `/**` 之前配置 | |||
4. **跨域支持**:两个拦截器都支持跨域配置 | |||
5. **多租户支持**:都支持多租户的TenantContext | |||
## 验证方法 | |||
1. **小程序接口**: | |||
- 访问 `/applet/health/health` 应该能正常访问(有@IgnoreAuth注解) | |||
- 访问 `/applet/user/info` 需要AppletJwtToken认证 | |||
2. **后台接口**: | |||
- 访问 `/sys/user/list` 需要JwtToken认证 | |||
- 访问 `/sys/login` 不需要认证(在anon列表中) | |||
3. **Token隔离**: | |||
- 后台Token无法用于小程序接口 | |||
- 小程序Token无法用于后台接口 | |||
## 扩展建议 | |||
1. **不同的Token格式**:可以为小程序和后台配置不同的JWT签名算法 | |||
2. **不同的权限模型**:可以为小程序配置更简单的权限体系 | |||
3. **不同的缓存策略**:可以为小程序配置不同的Token缓存时间 | |||
4. **不同的用户体系**:可以为小程序配置独立的用户表和管理逻辑 |
@ -1,234 +0,0 @@ | |||
# 小程序用户实体类配置说明 | |||
## 配置目标 | |||
完善小程序用户实体类,直接使用AppletUser作为登录对象,实现与后台用户体系的完全分离。 | |||
## 实现方案 | |||
### 1. 完善AppletUser实体类 | |||
#### 1.1 修改文件 | |||
- `jeecg-boot/jeecg-boot-module/jeecgboot-boot-applet/src/main/java/org/jeecg/modules/appletBackground/appletUser/entity/AppletUser.java` | |||
#### 1.2 新增字段 | |||
```java | |||
// 基础信息 | |||
private String username; // 用户名 | |||
private String password; // 密码 | |||
private String realname; // 真实姓名 | |||
private Date birthday; // 生日 | |||
private Integer sex; // 性别(1:男 2:女) | |||
private String email; // 邮箱 | |||
private Integer status; // 状态(1:正常 2:冻结) | |||
private Integer delFlag; // 删除标志(0代表存在 1代表删除) | |||
private Integer userIdentity; // 用户身份(1 普通用户 2 VIP用户) | |||
// 健康信息 | |||
private BigDecimal height; // 身高(cm) | |||
private BigDecimal weight; // 体重(kg) | |||
private Integer age; // 年龄 | |||
// 联系信息 | |||
private String address; // 地址 | |||
private String emergencyContact; // 紧急联系人 | |||
private String emergencyPhone; // 紧急联系人电话 | |||
// 会员信息 | |||
private String memberLevel; // 会员等级 | |||
private Integer points; // 积分 | |||
// 系统信息 | |||
private Date lastLoginTime; // 最后登录时间 | |||
private String deviceId; // 设备ID | |||
private String loginIp; // 登录IP | |||
private String remark; // 备注 | |||
``` | |||
### 2. 直接使用AppletUser作为登录对象 | |||
#### 2.1 配置说明 | |||
- 直接使用`AppletUser`实体类作为登录对象 | |||
- 不需要额外的VO类转换 | |||
- 简化了代码结构,减少了维护成本 | |||
#### 2.2 核心特性 | |||
```java | |||
@Data | |||
@TableName("applet_user") | |||
@Accessors(chain = true) | |||
@EqualsAndHashCode(callSuper = false) | |||
@Schema(description="小程序用户") | |||
public class AppletUser implements Serializable { | |||
// 基础信息 | |||
private String id; // 用户ID | |||
private String username; // 用户名 | |||
private String realname; // 真实姓名 | |||
private String name; // 昵称 | |||
private String password; // 密码 | |||
private String openid; // 第三方认证id | |||
private String avatar; // 头像 | |||
// 健康信息 | |||
private BigDecimal bmi; // 体总指数 | |||
private BigDecimal fat; // 脂肪 | |||
private BigDecimal height; // 身高 | |||
private BigDecimal weight; // 体重 | |||
private Integer age; // 年龄 | |||
// 其他信息 | |||
private Integer userIdentity; // 用户身份 | |||
private String memberLevel; // 会员等级 | |||
private Integer points; // 积分 | |||
private String deviceId; // 设备ID | |||
// ... 其他字段 | |||
} | |||
``` | |||
### 3. 修改小程序Realm | |||
#### 3.1 修改文件 | |||
- `jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/AppletShiroRealm.java` | |||
#### 3.2 配置变更 | |||
```java | |||
@Override | |||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { | |||
if (principals != null) { | |||
AppletUser appletUser = (AppletUser) principals.getPrimaryPrincipal(); | |||
username = appletUser.getUsername(); | |||
userId = appletUser.getId(); | |||
} | |||
// 小程序专用的权限认证逻辑 | |||
return info; | |||
} | |||
@Override | |||
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException { | |||
// 直接使用AppletUser进行身份认证 | |||
AppletUser loginUser = this.checkAppletUserTokenIsEffect(token); | |||
return new SimpleAuthenticationInfo(loginUser, token, getName()); | |||
} | |||
``` | |||
## 用户体系分离效果 | |||
### 1. 后台管理系统用户 | |||
- **实体类**:`SysUser` | |||
- **登录对象**:`LoginUser` | |||
- **Realm**:`ShiroRealm` | |||
- **适用场景**:后台管理系统的所有用户 | |||
### 2. 小程序用户 | |||
- **实体类**:`AppletUser` | |||
- **登录对象**:`AppletUser`(直接使用实体类) | |||
- **Realm**:`AppletShiroRealm` | |||
- **适用场景**:小程序相关的所有用户 | |||
## 配置优势 | |||
### 1. 完全独立的用户体系 | |||
- 小程序和后台使用不同的用户表 | |||
- 可以配置不同的用户属性和业务逻辑 | |||
- 支持不同的用户管理策略 | |||
### 2. 更好的业务适配 | |||
- 小程序用户包含健康相关的字段(BMI、身高、体重等) | |||
- 支持会员等级和积分系统 | |||
- 包含紧急联系人等小程序特有功能 | |||
### 3. 便于维护和扩展 | |||
- 小程序用户相关的逻辑独立管理 | |||
- 可以独立升级和配置 | |||
- 便于调试和问题排查 | |||
## 使用示例 | |||
### 1. 小程序用户注册 | |||
```java | |||
@PostMapping("/register") | |||
@Operation(summary = "小程序用户注册") | |||
public Result<AppletUser> register(@RequestBody AppletUser appletUser) { | |||
// 小程序用户注册逻辑 | |||
return Result.OK(appletUser); | |||
} | |||
``` | |||
### 2. 小程序用户登录 | |||
```java | |||
@PostMapping("/login") | |||
@Operation(summary = "小程序用户登录") | |||
public Result<AppletUser> login(@RequestBody LoginRequest request) { | |||
// 小程序用户登录逻辑 | |||
AppletUser loginUser = appletUserService.login(request); | |||
return Result.OK(loginUser); | |||
} | |||
``` | |||
### 3. 获取小程序用户信息 | |||
```java | |||
@GetMapping("/user/info") | |||
@Operation(summary = "获取小程序用户信息") | |||
public Result<AppletUser> getUserInfo() { | |||
// 获取当前登录的小程序用户信息 | |||
AppletUser user = (AppletUser) SecurityUtils.getSubject().getPrincipal(); | |||
return Result.OK(user); | |||
} | |||
``` | |||
## 数据库表结构 | |||
### applet_user表字段 | |||
```sql | |||
CREATE TABLE `applet_user` ( | |||
`id` varchar(32) NOT NULL COMMENT '主键', | |||
`create_by` varchar(32) DEFAULT NULL COMMENT '创建人', | |||
`create_time` datetime DEFAULT NULL COMMENT '创建日期', | |||
`update_by` varchar(32) DEFAULT NULL COMMENT '更新人', | |||
`update_time` datetime DEFAULT NULL COMMENT '更新日期', | |||
`sys_org_code` varchar(64) DEFAULT NULL COMMENT '所属部门', | |||
`name` varchar(100) DEFAULT NULL COMMENT '昵称', | |||
`openid` varchar(100) DEFAULT NULL COMMENT '第三方认证id', | |||
`phone` varchar(45) DEFAULT NULL COMMENT '手机号', | |||
`bmi` decimal(10,2) DEFAULT NULL COMMENT '体总指数', | |||
`fat` decimal(10,2) DEFAULT NULL COMMENT '脂肪', | |||
`avatar` varchar(255) DEFAULT NULL COMMENT '头像', | |||
`username` varchar(100) DEFAULT NULL COMMENT '用户名', | |||
`password` varchar(255) DEFAULT NULL COMMENT '密码', | |||
`realname` varchar(100) DEFAULT NULL COMMENT '真实姓名', | |||
`birthday` date DEFAULT NULL COMMENT '生日', | |||
`sex` int DEFAULT NULL COMMENT '性别(1:男 2:女)', | |||
`email` varchar(45) DEFAULT NULL COMMENT '邮箱', | |||
`status` int DEFAULT NULL COMMENT '状态(1:正常 2:冻结)', | |||
`del_flag` int DEFAULT NULL COMMENT '删除标志(0代表存在 1代表删除)', | |||
`user_identity` int DEFAULT NULL COMMENT '用户身份(1 普通用户 2 VIP用户)', | |||
`height` decimal(10,2) DEFAULT NULL COMMENT '身高(cm)', | |||
`weight` decimal(10,2) DEFAULT NULL COMMENT '体重(kg)', | |||
`age` int DEFAULT NULL COMMENT '年龄', | |||
`address` varchar(500) DEFAULT NULL COMMENT '地址', | |||
`emergency_contact` varchar(100) DEFAULT NULL COMMENT '紧急联系人', | |||
`emergency_phone` varchar(45) DEFAULT NULL COMMENT '紧急联系人电话', | |||
`member_level` varchar(50) DEFAULT NULL COMMENT '会员等级', | |||
`points` int DEFAULT NULL COMMENT '积分', | |||
`last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间', | |||
`device_id` varchar(100) DEFAULT NULL COMMENT '设备ID', | |||
`login_ip` varchar(100) DEFAULT NULL COMMENT '登录IP', | |||
`remark` varchar(500) DEFAULT NULL COMMENT '备注', | |||
PRIMARY KEY (`id`) | |||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='小程序用户表'; | |||
``` | |||
## 注意事项 | |||
1. **用户体系隔离**:小程序和后台使用完全不同的用户表 | |||
2. **字段差异**:小程序用户包含健康相关的字段 | |||
3. **业务逻辑**:小程序用户支持会员等级和积分系统 | |||
4. **安全策略**:可以为小程序配置不同的安全策略 | |||
5. **缓存策略**:可以为小程序用户配置独立的缓存策略 | |||
## 后续开发建议 | |||
1. **实现getAppletUser方法**:需要根据实际的AppletUser服务来实现 | |||
2. **添加小程序用户服务**:创建AppletUserService来处理用户相关业务 | |||
3. **配置小程序用户权限**:为小程序用户配置独立的角色和权限体系 | |||
4. **添加健康数据管理**:实现BMI、体重等健康数据的计算和管理 | |||
5. **实现会员系统**:实现会员等级和积分系统 |