Skip to content

登录与路由拦截

RouteInterceptor.ktUserState 共同构成了“必须登录页面”的守卫机制。ViewModel 在每次调用 navigate() 时都会经过该拦截器,如果用户尚未登录,便自动切换到登录页,无需业务代码重复判断。

RouteInterceptor

核心逻辑非常简单:维护一个 MutableSet<KClass<out Any>>,其中存放所有“需要登录”的路由类型,默认示例:

kotlin
private val loginRequiredRouteTypes = mutableSetOf(
    UserRoutes.Info::class
)

提供的方法:

方法说明
requiresLogin(route: Any)判断指定路由对象是否在白名单之外。
getLoginRoute()返回登录页(默认 AuthRoutes.Login),可按需改写。
addLoginRequiredRoute(routeClass) / removeLoginRequiredRoute(routeClass)动态管理需要登录的路由集合。
getLoginRequiredRoutes()查看当前配置,方便调试。

BaseViewModel 如何接入

BaseViewModel.navigate() 会在真正调用 AppNavigator 前执行 checkRouteInterception(route)

kotlin
private fun checkRouteInterception(route: Any): Any {
    return if (routeInterceptor.requiresLogin(route) && !userState.isLoggedIn.value) {
        routeInterceptor.getLoginRoute()
    } else {
        route
    }
}

因此业务 ViewModel 完全不需要关心登录判断,只需调用 navigate(TargetRoute)。若未登录,则会自动跳转到登录页,登录成功后再由登录页自行负责后续逻辑。

配置建议

  1. 集中注册:在应用启动或 Feature 模块初始化时,根据业务需要调用 routeInterceptor.addLoginRequiredRoute(MyRoutes.xxx::class),保持列表与产品策略一致。
  2. 结合 UserStateuserState.isLoggedIncore/state 维护,确保登录/登出/刷新 token 会实时通知拦截逻辑。
  3. 多级 Guard:若需要更复杂的 Guard(例如会员专属页),可以扩展 RouteInterceptor,增加新的集合或策略,然后在 BaseViewModel 中加入相应判断。
  4. 测试与调试getLoginRequiredRoutes() 可以打印当前配置,便于联调。

通过这套 Guard,导航路径保持类型安全的同时,登录态控制也统一在一个地方,实现“哪里需要登录,只需登记一次”的效果。