26 lines
1.1 KiB
Dart
26 lines
1.1 KiB
Dart
import 'dart:convert';
|
|
|
|
/// 本地解析 JWT 的 exp 字段,判断是否已过期。
|
|
///
|
|
/// 目的:App 启动时立刻发现"登录已过期",不必先发一次请求才报错。
|
|
/// 注意:只做本地时间判断,不校验签名——签名的真伪由后端负责。
|
|
/// 返回 false(视为未过期)的条件:token 不是标准 JWT 格式或没有 exp 字段,
|
|
/// 避免因格式差异把正常登录态误判为过期。
|
|
bool isJwtExpired(String? token, {Duration leeway = const Duration(seconds: 30)}) {
|
|
if (token == null || token.isEmpty) return true;
|
|
final parts = token.split('.');
|
|
if (parts.length != 3) return false;
|
|
|
|
try {
|
|
final payload = utf8.decode(base64Url.decode(base64Url.normalize(parts[1])));
|
|
final claims = jsonDecode(payload);
|
|
if (claims is! Map) return false;
|
|
final exp = claims['exp'];
|
|
if (exp is! num) return false; // 无 exp 字段 → 不做本地判断
|
|
final expireAt = DateTime.fromMillisecondsSinceEpoch(exp.toInt() * 1000);
|
|
return expireAt.isBefore(DateTime.now().add(leeway));
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|