Files
go-admin/cmd/migrate/migration/version/1786700002000_remove_refresh_token_api.go
T
zhangwenjian b81611ba72 chore🔧: 清理 refresh_token 的残留权限数据
接口移除后,库中仍留有三类记录:sys_api 的接口登记、sys_menu_api_rule 的
菜单绑定、casbin_rule 的策略。留着会让「接口管理」列出一个不存在的端点,
角色配置里也仍可勾选。

- 新装:从 db.sql 与 db-sqlserver.sql 的种子数据中删除该接口
- 已有部署:新增迁移清理,按 path 匹配而非固定 id,因为执行过
  `server -a` 重新注册接口的库中 id 会与官方种子数据不同
2026-08-14 21:42:59 +08:00

62 lines
2.1 KiB
Go

package version
import (
"runtime"
"gorm.io/gorm"
"go-admin/cmd/migrate/migration"
"go-admin/cmd/migrate/migration/models"
common "go-admin/common/models"
)
// 清理 GET /api/v1/refresh_token 的残留权限数据。
//
// 该路由已随 issue #820 的修复移除:它允许用业务 token 换取新 token,而续期
// 上限 MaxRefresh 依据的 orig_iat 每次续期都被重置,上限永远无法到达。
//
// 路由虽已删除(请求会返回 404),但已有部署的库中仍残留三类记录:接口登记、
// 菜单与接口的绑定、Casbin 策略。留着会让「接口管理」列出一个不存在的端点,
// 角色配置里也仍可勾选,造成误解。
//
// 按 path 匹配而非固定 id —— 使用者若执行过 `server -a` 重新注册接口,id 会
// 与官方种子数据不同。
func init() {
_, fileName, _, _ := runtime.Caller(0)
migration.Migrate.SetVersion(migration.GetFilename(fileName), _1786700002000RemoveRefreshTokenApi)
}
const refreshTokenPath = "/api/v1/refresh_token"
func _1786700002000RemoveRefreshTokenApi(db *gorm.DB, version string) error {
return db.Transaction(func(tx *gorm.DB) error {
var apiIds []int
if err := tx.Model(&models.SysApi{}).
Where("path = ? AND action = ?", refreshTokenPath, "GET").
Pluck("id", &apiIds).Error; err != nil {
return err
}
if len(apiIds) > 0 {
// 先断开绑定,再删接口本身,避免遗留悬空外键
// 连接表由 GORM many2many 生成,列名为 sys_api_id 而非 api_id
if err := tx.Exec("DELETE FROM sys_menu_api_rule WHERE sys_api_id IN ?", apiIds).Error; err != nil {
return err
}
if err := tx.Where("id IN ?", apiIds).Delete(&models.SysApi{}).Error; err != nil {
return err
}
}
// casbin_rule 才是 adapter 实际使用的表,策略按路径存储,与 sys_api 的
// id 无关,因此即使上面没匹配到接口也要清理
if err := tx.Exec(
"DELETE FROM casbin_rule WHERE ptype = 'p' AND v1 = ?", refreshTokenPath,
).Error; err != nil {
return err
}
return tx.Create(&common.Migration{Version: version}).Error
})
}