🏠 Home

Zero Auth

A backend-agnostic auth state machine & session lifecycle core for Dart/Flutter. Pure Dart, headless, no HTTP/SDK/native code. Wire your own backend via AuthStrategy and your own persistence via TokenStore.

一个后端无关的认证状态机与会话生命周期内核,面向 Dart/Flutter。纯 Dart、无头(headless),不含 HTTP、SDK 或原生代码。通过 AuthStrategy 接入自有后端,通过 TokenStore 接入自有持久化层。

✨ Features / 功能特性

FeatureDescription
Backend-agnosticImplement only login/register/logout/refresh; REST, gRPC, Firebase or a private RPC are equally valid targets / 只需实现四个方法,REST、gRPC、Firebase 或私有 RPC 均可接入
Auth State MachineSealed Unauthenticated / Authenticating / Authenticated / Refreshing / LoggingOut / AuthError on a Stream<AuthState> that replays the latest value to new listeners; use isAuthenticated / isBusy / 密封六态状态机 + 重放最近值的状态流,可用 isAuthenticated / isBusy
Silent Restorerestore() rehydrates the persisted session at startup / 启动时静默恢复持久化会话
Single-flight RefreshConcurrent refresh() calls share one in-flight request instead of stampeding the backend / 并发刷新共享同一次请求,避免冲击后端
Pluggable PersistenceThe only persistence surface is TokenStore.save/load/clear; InMemoryTokenStore ships in-core / 唯一的持久化接口,内核自带内存实现
Typed SessionAuthSession carries access/refresh tokens, expiry (isExpired), user id, display name and raw claims / 强类型会话,无需手工解析令牌
Unified ErrorsEvery failure maps to AppException (AuthException for auth cases) or a Result<T> wrapper; raw exceptions never cross the public surface / 统一异常与结果,裸异常不越界
Network IntegrationAuthManager itself is an AuthTokenSource, so a Dio interceptor can attach Authorization: Bearer without depending on the manager / 管理器即令牌源,Dio 拦截器零依赖附加令牌
Session SerializationAuthSession.toJson / fromJson make persistence a one-liner, and tryFromJson returns null on malformed data; a file-based reference store ships for server/CLI / AuthSession.toJson / fromJson 让持久化一行搞定,tryFromJson 遇畸形数据返回 null,并附带面向服务端 / CLI 的文件参考存储
Proactive Auto-refreshPass autoRefreshAhead to renew tokens before expiry (single-flight) / 传入 autoRefreshAhead 在过期前自动续期(单飞)
Never an Expired TokenvalidAccessToken() renews first when the token has expired — or is about to, per clockSkew — so interceptors never send a dead bearer token / 令牌过期(或按 clockSkew 即将过期)时先续期,拦截器不会发出失效令牌
Bring Your Own LoginloginWith adopts a session from any flow you drive: third-party OAuth, magic links, passkeys / loginWith 可接纳第三方 OAuth、魔法链接、Passkey 等自定义流程
Typed Auth ExceptionsInvalidCredentialsException, SessionExpiredException and friends, mapped from your strategy’s code / InvalidCredentialsException、SessionExpiredException 等,由策略的 code 映射而来
Configurable Failure PolicyrefreshFailurePolicy decides whether a failed refresh signs the user out / refreshFailurePolicy 决定刷新失败是否登出
Runnable ExampleA full Flutter demo app (Android/iOS/Web/Windows) plus a layered dart:io demo backend that issues real JWTs / 完整 Flutter 示例与一个签发真实 JWT 的分层演示后端
Multiple AccountsOptional AuthManagerGroup keeps one manager per account / 可选 AuthManagerGroup,每账号一个管理器
Cross-platformPure Dart — runs anywhere Dart or Flutter runs / 纯 Dart,跨平台

📚 Table of Contents / 目录

PageDescription
Getting StartedQuick start guide / 快速开始
InstallationHow to install / 安装方式
UsageDetailed usage / 详细使用
Auth State MachineState lifecycle & stream / 状态机与状态流
Backend StrategyImplement AuthStrategy / 实现后端边界
Token StorePersistence boundary / 持久化边界
Network IntegrationDio interceptor & token source / 网络集成与拦截器
ErrorsException & Result model / 异常与结果模型
ConfigurationConfiguration options / 配置说明
Session PersistenceRestoring and renewing a saved session / 会话持久化与恢复
Third-Party LoginOAuth / magic links via loginWith / 用 loginWith 接入第三方登录
Multiple AccountsSwitching vs concurrent accounts / 账号切换与多账号并存
FAQFrequently asked questions / 常见问题

📄 License / 许可证

This project is licensed under the Mozilla Public License 2.0 (MPL-2.0).

本项目采用 Mozilla Public License 2.0 (MPL-2.0) 许可证。

This package is provided “as is”, without warranty of any kind. The author assumes no responsibility or liability for the functionality, security, or any consequences arising from the use of modified versions or derivative projects.

本包按”原样”提供,不提供任何担保。作者不对修改版或衍生项目的功能、安全性及任何使用后果承担责任。