修改日期:2026-06-15 | 需求:后端一站式处理粤信签认证,前端只需传入loginToken即可完成全部登录流程
后端新增 /zjrs/login/yxqMiniProgramLogin 接口,接收前端传入的粤信签loginToken,内部一站式完成:
核心优化: 将原来前端需要3次网络请求的登录流程,简化为前端1次请求,后端内部完成全部逻辑。
ILoginSSOService.java - Service接口文件路径: jeecg-boot-module/jeecg-module-zjrs/src/main/java/org/jeecg/modules/zjrs/sso/service/ILoginSSOService.java
新增方法:
/**
* 粤信签小程序登录
* 前端传入粤信签返回的loginToken,后端内部调用省统一认证网关完成:
* 1. 用loginToken换取Access-Token
* 2. 用Access-Token获取用户信息(姓名、身份证号、用户类型等)
* 3. 根据用户信息匹配本地数据库(PERSONAL_INFO或ENTERPRISE_INFO)
* 4. 签发JeecgBoot业务token
*
* @param loginToken 粤信签小程序返回的登录token
* @param request 请求对象
* @return 登录结果(包含token、loginType、personalInfoId/enterpriseInfoId等)
* @throws RuntimeException 登录失败时抛出异常
*/
JSONObject yxqMiniProgramLogin(String loginToken, HttpServletRequest request);
LoginSSOServiceImpl.java - Service实现文件路径: jeecg-boot-module/jeecg-module-zjrs/src/main/java/org/jeecg/modules/zjrs/sso/service/impl/LoginSSOServiceImpl.java
新增配置常量:
/** 省统一认证平台申请ID */
private static final String PAAS_ID = "yxq_zjsrlzyhshbzggfwpt";
/** 省统一认证平台申请密钥 */
private static final String PAAS_TOKEN = "TSgNKaU3wFw1WwtdAoTE0cT57UisJs5p";
/** 网关基础地址(通过配置文件注入,默认值用于本地开发) */
@Value("${zjrs.yxq.gateway-url:https://rsj.zhanjiang.gov.cn/wx}")
private String gatewayBaseUrl;
新增方法:
| 方法 | 说明 |
|---|---|
yxqMiniProgramLogin() |
入口方法,接收loginToken,内部调用网关验证+获取用户信息+匹配数据库+签发token |
getAccessTokenFromGateway() |
用loginToken调用省统一认证网关 /api/auth/tyrz/miniprogram,换取Access-Token |
getYxqUserInfo() |
用Access-Token调用 /ggfw/api/portal/user/getUserInfo,获取用户信息 |
matchPersonalAndCreateToken() |
个人用户匹配:优先身份证号精确匹配,其次姓名匹配 |
matchEnterpriseAndCreateToken() |
企业用户匹配:根据企业名称匹配 |
sha256() |
SHA256哈希算法,用于生成粤信签网关签名 |
关键优化 - 个人用户匹配策略:
aac002)精确匹配 personal_info.id_number,避免同名冲突personal_info.full_namegetOne(qw, false) 避免多条记录时抛出 TooManyResultsException新增import:
import org.jeecg.common.util.RestUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.UUID;
LoginSSOController.java - Controller文件路径: jeecg-boot-module/jeecg-module-zjrs/src/main/java/org/jeecg/modules/zjrs/sso/controller/LoginSSOController.java
新增接口:
@PostMapping("/yxqMiniProgramLogin")
@IgnoreAuth
@Operation(summary = "粤信签小程序登录", description = "前端传入粤信签loginToken,后端内部调用省统一认证网关完成认证并签发JeecgBoot业务token")
public Result<JSONObject> yxqMiniProgramLogin(@RequestBody JSONObject params, HttpServletRequest request) {
try {
String loginToken = params.getString("loginToken");
JSONObject result = loginSSOService.yxqMiniProgramLogin(loginToken, request);
return Result.OK(result);
} catch (RuntimeException e) {
log.error("粤信签小程序登录失败", e);
return Result.error(e.getMessage());
}
}
ShiroConfig.java - Shiro安全配置文件路径: jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
修改内容:
filterChainDefinitionMap.put("/zjrs/login/yxqMiniProgramLogin", "anon"); // 粤信签小程序登录
POST /zjrs/login/yxqMiniProgramLoginjson
{
"loginToken": "粤信签小程序返回的token"
}
{
"success": true,
"result": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"loginType": "personal",
"personalInfoId": "1906017267265433601",
"yxqUserInfo": { "aac003": "张三", "fwdx": "1", ... },
"loginFlag": true
}
}
接收 loginToken
↓
getAccessTokenFromGateway()
POST {gateway-url}/api/auth/tyrz/miniprogram
参数:code, x_tif_paasid, x_tif_signature, x_tif_timestamp, x_tif_nonce
签名:sha256(时间戳 + paaSToken + 随机数 + 时间戳)
返回:Access-Token
↓
getYxqUserInfo()
GET {gateway-url}/ggfw/api/portal/user/getUserInfo
请求头:Access-Token
返回:{ aac003: 姓名, aac002: 身份证号, fwdx: 用户类型 }
↓
根据 fwdx 判断登录类型(1=个人,2=企业)
↓
个人用户:
matchPersonalAndCreateToken()
1. 优先用身份证号(aac002)匹配 personal_info.id_number
2. 匹配不到再用姓名(aac003)匹配 personal_info.full_name
3. 生成 "personal_" + id 的用户名
4. 调用 createToken() 签发JWT
企业用户:
matchEnterpriseAndCreateToken()
1. 用企业名称(aac003)匹配 enterprise_info.company_name
2. 生成 "enterprise_" + id 的用户名
3. 调用 createToken() 签发JWT
↓
返回 { token, loginType, personalInfoId/enterpriseInfoId, yxqUserInfo, loginFlag }
网关地址配置: 默认 https://rsj.zhanjiang.gov.cn/wx,如JeecgBoot部署在内网无法直接访问外网,需在 application.yml 中配置 zjrs.yxq.gateway-url 代理地址。
无需新增依赖: 使用项目已有的 RestUtil(基于 RestTemplate + Apache HttpClient)。
个人用户匹配策略: 优先身份证号精确匹配,解决了原来仅用姓名匹配可能导致的同名冲突问题。
安全加固: paaSToken密钥存储在后端,不再暴露在前端。
不影响现有逻辑: 原有的 miniProgramPersonalLogin 和 miniProgramEnterpriseLogin 接口保持不变。