登录与路由拦截
RouteInterceptor.kt 与 UserState 共同构成了“必须登录页面”的守卫机制。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)。若未登录,则会自动跳转到登录页,登录成功后再由登录页自行负责后续逻辑。
配置建议
- 集中注册:在应用启动或 Feature 模块初始化时,根据业务需要调用
routeInterceptor.addLoginRequiredRoute(MyRoutes.xxx::class),保持列表与产品策略一致。 - 结合 UserState:
userState.isLoggedIn由core/state维护,确保登录/登出/刷新 token 会实时通知拦截逻辑。 - 多级 Guard:若需要更复杂的 Guard(例如会员专属页),可以扩展
RouteInterceptor,增加新的集合或策略,然后在BaseViewModel中加入相应判断。 - 测试与调试:
getLoginRequiredRoutes()可以打印当前配置,便于联调。
通过这套 Guard,导航路径保持类型安全的同时,登录态控制也统一在一个地方,实现“哪里需要登录,只需登记一次”的效果。