6979411c1d
dev 本机置备(新增 dev/):
- docker-compose.yml: MySQL :13306 + Redis :16379(避让本机已占的 3306/6379)
- run-local.sh 一键: 起容器→openssl 生成密钥(dev/.local gitignore)→migrate→
seed→启动 server :18080(避让 8080);LogMailer 把验证码打日志
- seed.sql(1 provider + 1 HK 节点)、run-local.md 手册、.gitignore
后端两处修复(本地无 gRPC 场景,注释意图与代码不符的 bug):
- main.go: 无 gRPC 时真正构造 Hub-only nodeSvc(原只建 hub 没赋值),/v1/nodes 才能挂
- main.go: /me 改 Route 子路由根 Get,修 Get("/me")+Route("/me") 冲突致 404
客户端接真后端:
- token_store: MacOsOptions(useDataProtectionKeyChain:false) 修 keychain -34018
- auth_screen: 删 dev 旁路(test 账户内存登录),所有登录走真 API
验收: 后端 curl 端到端全通(验证码→注册→登录→/nodes→/me);
server go build/vet/test 通过, client analyze 0 + test 84
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
33 lines
1.1 KiB
Dart
33 lines
1.1 KiB
Dart
// token_store.dart — JWT 令牌安全持久化(flutter_secure_storage 封装)
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
|
|
class TokenStore {
|
|
const TokenStore({FlutterSecureStorage? storage})
|
|
: _storage = storage ?? const FlutterSecureStorage(
|
|
// macOS 用文件式 keychain,避免未签名 app 缺 keychain-access-groups
|
|
// entitlement 时 write 报 -34018。
|
|
mOptions: MacOsOptions(useDataProtectionKeyChain: false),
|
|
);
|
|
|
|
final FlutterSecureStorage _storage;
|
|
|
|
static const _kAccess = 'pangolin_access_token';
|
|
static const _kRefresh = 'pangolin_refresh_token';
|
|
|
|
Future<void> saveTokens({
|
|
required String access,
|
|
required String refresh,
|
|
}) async {
|
|
await _storage.write(key: _kAccess, value: access);
|
|
await _storage.write(key: _kRefresh, value: refresh);
|
|
}
|
|
|
|
Future<String?> loadAccessToken() => _storage.read(key: _kAccess);
|
|
Future<String?> loadRefreshToken() => _storage.read(key: _kRefresh);
|
|
|
|
Future<void> clear() async {
|
|
await _storage.delete(key: _kAccess);
|
|
await _storage.delete(key: _kRefresh);
|
|
}
|
|
}
|