登录 token 补齐与项目改动全量汇总

导读

链路通了,admin 也起来了,但登录返回的响应没有 token——因为 token 是 Gateway 加的,不是 admin 加的。本篇解决:登录 token 补齐 + Nacos 分组统一 + admin 注册 Nacos + 980.sql 数据导入,以及一份完整的项目改动清单(5 个我们改的代码文件 + 3 个 dist_sync 分支已有的改动)。

🎧 文章导读

🎵 背景音乐

前言

昨天把启动链路打通,今天登录后端点通了,但新问题又冒出来:

  1. 登录响应没有 token 字段
  2. Gateway 报 Load balancer does not contain an instance for the service admin
  3. 登录后 /user/info 返回的菜单是空的

每个问题背后都藏着一个独立的修复故事。

登录调用链架构图
图1:前端→Gateway→admin 调用链

问题 1:登录响应没有 token

现象

本地 POST /admin/user/login 返回:

1
2
3
4
5
6
7
8
9
{
"respCode": "200",
"data": {
"realName": "admin",
"login_serial": "1:1781057888640",
"roleCodeList": ["super_admin"]
// 没有 token 和 loginUser 字段
}
}

线上返回却有 token 字段——差别在 Gateway。

根因

token 是在 Gateway 层加的,不是 admin-service 自己加的

线上调用链:

1
前端 → Gateway(:10001) → ModifyAuthRespFilter 拦截 login → jwtTokenService.afterLoginProcess() → 加 token → 转发到 admin-service

ModifyAuthRespFilter(在 xxkj-framework/.../service-gateway/.../ModifyAuthRespFilter.java)会检查请求路径是否在 jwtAuthProperties.getLoginRelaApis() 集合中,匹配才拦截并加 token。

修复

Nacos 配置 application.yml(在 smart-building 分组下)原来只有 publicApiPatterns,**缺 loginRelaApislogoutRelaApis**:

1
2
3
4
5
6
7
8
9
10
icfg:
auth:
loginRelaApis:
- /admin/user/login
logoutRelaApis:
- /admin/user/logout
publicApiPatterns:
- /admin/user/login
- /admin/user/logout
- /admin/captcha/image

三个白名单字段的区别

字段 作用
loginRelaApis Gateway 拦截这些路径,加 token 再返回
logoutRelaApis Gateway 拦截这些路径,清除 token
publicApiPatterns 免鉴权路径(不校验 token 就能访问)

[!warning] 配置错位代价高
登录接口需要同时配 loginRelaApispublicApiPatterns——前者让 Gateway 加 token,后者让 Gateway 放行请求。少了任何一个,登录都会失败。

问题 2:Nacos 分组名不一致

现象

登录成功后访问 /admin/user/info 报 500:

1
Load balancer does not contain an instance for the service admin

根因

Gateway 和 admin-service 的 Nacos 分组默认值不一致:

服务 默认分组 实际
Gateway ${NACOS_GROUP:smart_building}(下划线) ❌ 与其他服务不同
admin-service ${NACOS_GROUP:smart-building}(中划线)
其他 10 个服务 ${NACOS_GROUP:smart-building}(中划线)

10 个服务用中划线,只有 Gateway 用下划线。导致 Gateway 发现不了其他服务。

修复

只改了 Gateway 一个文件,5 处 smart_buildingsmart-building

1
2
3
4
5
6
# xxkj-framework/xxkj-framework-services/service-gateway/src/main/resources/bootstrap.yml
spring.cloud.nacos.discovery.group: smart-building
spring.cloud.nacos.config.group: smart-building
shared-configs[0].group: smart-building # application.yml
shared-configs[1].group: smart-building # application-auth.yml
shared-configs[2].group: smart-building # application-${spring.profiles.active}.yml

Nacos 配置迁移

  • smart-building 分组下创建 application.yml(内容同原 smart_building 分组下的)
  • 删除 smart_building 分组下的 application.yml

[!warning] 改 group 名的连锁反应
改 group 名之前必须先把 Nacos 上的配置复制到新 group,否则所有服务会发现不了配置,全部 404。

问题 3:admin-service 没注册到 Nacos

现象

即使分组统一了,admin-service 仍然注册不上 Nacos。

根因

admin-servicebootstrap-dev.yml 第 6 行:

1
register-enabled: false

dev 配置关闭了 Nacos 服务注册。原作者本地开发时可能不需要服务发现(通过 feign-url 直连),但 Gateway 的 AccessControlFilter 需要通过服务发现找到 admin 来查权限

修复

1
2
# service-provider/admin-service/src/main/resources/bootstrap-dev.yml
register-enabled: false register-enabled: true

[!tip] 注册 ≠ 服务发现
Nacos 注册(discovery)让其他服务通过服务名找到你;Nacos 配置(config)让你从 Nacos 拉配置。dev 默认关注册是因为本地可以用 feign-url 直连——但 Gateway 是个例外,它必须通过 Nacos 发现下游服务。

Nacos 分组迁移示意
图2:Nacos 分组名统一迁移

问题 4:本地数据库缺基础数据

现象

登录成功后 /user/info 返回:

1
2
3
4
5
6
7
{
"menus": [],
"resFunctions": [],
"parkId": null,
"parkName": null,
"orgId": null
}

前端显示”无权限访问”。

根因

本地数据库只有 Flyway 建的空表,没有基础数据:

  • sys_park:空的 → 没有园区
  • sys_organization:空的 → 没有机构
  • sys_user_park:空的 → 用户没分配园区
  • sys_user_organization:空的 → 用户没分配机构
  • sys_resource:空的 → 没有菜单资源
  • sys_role_resource:空的 → 角色没有权限

UserController.userInfo()resourceService.selectUserResources(appId, userId, endpoint, parkId) —— parkId 为 null 导致查不到菜单。

修复

使用 E:\nanwang\项目会用压缩包\980.sql(从线上 10.182.5.215 导出的 building_admin 完整 mysqldump)直接导入:

1
mysql -h 127.0.0.1 -u building_admin -p'building_admin@123' building_admin < 980.sql

导入后数据量

行数
sys_user 6365
sys_park 8
sys_organization 664
sys_user_park 1116
sys_user_organization 42510
sys_resource 702
sys_role_resource 1870
sys_role 75
sys_user_role 242

[!warning] dump 的副作用
这个 dump 有 DROP TABLE IF EXISTS,会覆盖现有表结构和数据。导入后 Flyway 的 flyway_schema_history 表会被删掉(dump 里没有这张表),但不影响启动——Flyway 检测到表已存在会跳过建表。

改动文件 diff 汇总
图3:5 个文件改动分布

项目改动全量汇总

E:\nanwang\原后端\smart-park-cloud - no jar\smart-park-cloud - no jar(完全没改过的原始副本)为基准,对比当前代码的所有差异。

我们改的(5 个代码文件 + 环境配置)

1. admin-service/src/main/resources/bootstrap-dev.yml

1 行改动register-enabled: falsetrue

原因:dev 配置关闭了 Nacos 服务注册,Gateway 的 AccessControlFilter 找不到 admin 服务。

2. property-service/src/main/resources/bootstrap-dev.yml

4 处 IP 替换10.152.238.245127.0.0.1

1
2
3
NACOS_SERVER:10.152.238.245:8848  →  127.0.0.1:8848
MYSQL_SERVER:10.152.238.245:3306 → 127.0.0.1:3306
redis host: 10.152.238.245 → 127.0.0.1

3. through-service/src/main/resources/bootstrap-dev.yml

3 处新增

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 新增1:关闭 Nacos 配置中心(本地不走 Nacos 拉配置)
config:
enabled: false

# 新增2:admin 服务名
icfg:
admin:
service-id: admin

# 新增3:feign-url 直连地址补全
feign-url:
through: http://127.0.0.1:18134
security: http://127.0.0.1:18135
iot: http://127.0.0.1:18350

4. service-gateway/src/main/resources/bootstrap-dev.yml

**新增 deploymentsfeign-url**:11 个服务的本地端口映射。

5. service-util/pom.xml

注释掉 com.sun.jna 两个依赖

1
2
3
4
5
6
7
<!--
<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>examples</artifactId>
<version>1.0.0</version>
</dependency>
-->

原因com.sun.jna:examples:1.0.0 在全球公共 Maven 仓库均不存在,项目内零代码引用。

环境配置改动(非代码)

# 改动 说明
1 E:\maven363\...\settings.xml 重写,移除内网仓库,只保留阿里云镜像
2 本地 Maven 仓库 F:\LocalWarehouse 新增 xxkj、ojdbc8、swift-java-api、kaptcha、elastic-job 等 jar
3 Nacos 配置 新建 smart-building 分组,含 loginRelaApis 等;删除旧的 smart_building 分组
4 本地数据库 building_admin 导入 980.sql(线上完整 dump)
5 Git 恢复的 jar(7 个) integrate-iot/{dataphinlibs,massmslibs,mqslibs}/*.jar 从 git 恢复

拿到手就已经改了的(不是我们改的)

以下文件在原始副本里就已经和 git 上的不同了,说明是别人在 dist_sync 分支上提交的:

1. PassUserGrantServiceImpl.java

1
2
3
4
// 执行成功时 → 执行成功或失败时
if (Objects.equals(grantExecStatus, "2") || Objects.equals(grantExecStatus, "3")) {
updateGrant.setDistSyncStatus(PaasDistSyncStatus.PENDING.getStatus());
}

属于 dist_sync 分支的业务功能:下发失败也标记为待同步。

2. AlarmingEvenSinkServiceImpl.java

  • 方法重命名:antiGravityVerificationallowGenRepeatAlarmRecord
  • 返回值取反:3 处 return this.doesXxx(...)return !this.doesXxx(...)

属于 dist_sync 分支的 bug 修复:原逻辑返回值语义反转导致重复告警判断错误。

3. AlarmingRecordMapper.xml

1
2
3
<!-- 新增排序 -->
ORDER BY alarm_time DESC
LIMIT 1

属于 dist_sync 分支的功能修改。

未改动的文件(git 显示有差异但实际没改)

文件 实际情况
QrCodeByIdTypeUtils.java 只有换行符(CRLF/LF)差异,内容完全一致
gateway/bootstrap.yml 只有换行符差异,内容完全一致

改动总结

5 个文件的本地环境适配,全部是配置文件(bootstrap-dev.ymlpom.xml),没有改任何业务逻辑代码。

核心目的

  1. 让服务连本地 Nacos/MySQL/Redis(改 IP、开注册)
  2. 让 Gateway 知道本地各服务的端口(加 deployments 和 feign-url)
  3. 解决一个编译依赖缺失(注释掉 jna)

零 Java 业务代码改动——这是接手烂尾项目最理想的状况:环境层全清,业务层不碰。

当前状态

节点 状态
前端 → Gateway → admin ✅ 通
登录返回 token ✅ 已修复
admin-service 注册 Nacos ✅ 已修复
Nacos 分组统一 ✅ 已修复
数据库基础数据 ✅ 已导入
登录后菜单/权限 ✅ 应该正常
其他服务(through、aided 等) ⏳ 未启动

经验总结

改动分类的纪律

接手别人代码时,先做分类:我们改的 vs 别人改的 vs 仅换行符差异。这条纪律帮我后续排查问题时能直接定位”这改动是不是我的”——避免改了一个看似无关的代码导致预期外 bug。

数据库 dump 的局限性

980.sql 解决了基础数据问题,但同时带来:

  • 不能复用生产数据:含真实手机号、身份证号,导入到本地 dev 环境存在合规风险
  • Flyway 历史丢失:dump 没 flyway_schema_history 表,启动 Flyway 会重新比对 baseline,可能造成 migrate 失败
  • 测试隔离差:所有人共用同一份数据,单元测试不可重复

长远看应该用 Flyway 迁移脚本 + 种子数据脚本代替完整 dump。

反编译 jar 是必备技能

com.xxkj:common-auth 这种私有 jar 的字段名,靠 javap 反编译就能拿到。这比猜测快 10 倍。

下一步

基础环境全部到位,下一篇进入真正的业务功能开发:钉钉同步补 sys_user_park 写入 + 园区绑定一级公司 + MyBatis OGNL 那个经典踩坑。