20260615-粤信签登录后端一站式接口开发记录.md 6.9 KB

粤信签登录集成 - 后端修改记录

修改日期:2026-06-15 | 需求:后端一站式处理粤信签认证,前端只需传入loginToken即可完成全部登录流程


一、修改概述

后端新增 /zjrs/login/yxqMiniProgramLogin 接口,接收前端传入的粤信签loginToken,内部一站式完成:

  1. 调用省统一认证网关换取Access-Token
  2. 用Access-Token获取用户信息(姓名、身份证号、用户类型等)
  3. 根据用户信息匹配本地数据库(PERSONAL_INFO或ENTERPRISE_INFO)
  4. 签发JeecgBoot业务token并返回

核心优化: 将原来前端需要3次网络请求的登录流程,简化为前端1次请求,后端内部完成全部逻辑。


二、修改文件清单

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);

2. 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_name
  • 使用 getOne(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;

3. 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());
    }
}

4. ShiroConfig.java - Shiro安全配置

文件路径: jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java

修改内容:

filterChainDefinitionMap.put("/zjrs/login/yxqMiniProgramLogin", "anon"); // 粤信签小程序登录

三、接口说明

请求

  • URL: POST /zjrs/login/yxqMiniProgramLogin
  • 参数: json { "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 }

五、注意事项

  1. 网关地址配置: 默认 https://rsj.zhanjiang.gov.cn/wx,如JeecgBoot部署在内网无法直接访问外网,需在 application.yml 中配置 zjrs.yxq.gateway-url 代理地址。

  2. 无需新增依赖: 使用项目已有的 RestUtil(基于 RestTemplate + Apache HttpClient)。

  3. 个人用户匹配策略: 优先身份证号精确匹配,解决了原来仅用姓名匹配可能导致的同名冲突问题。

  4. 安全加固: paaSToken密钥存储在后端,不再暴露在前端。

  5. 不影响现有逻辑: 原有的 miniProgramPersonalLoginminiProgramEnterpriseLogin 接口保持不变。