dart SharedPreferences Flutter..集过期时间

e0uiprwp  于 2023-09-28  发布在  Flutter
关注(0)|答案(3)|浏览(140)

我在申请Flutter
我有一个来自API的访问令牌,我保存在共享首选项中用于会话管理和身份验证。
但这里的问题是,这个令牌每1小时过期一次,所以我需要每1小时清除一次共享的首选项。
使用的 Package -shared_preferences
那么,我该怎么做呢??

yduiuuwa

yduiuuwa1#

这是我的解决方案。我使用了一个功能丰富的包,它可以帮助我们解码JWT令牌。解码意味着提取信息。
我用过:jwt_decoder

import "dart:developer";

import "package:flutter/material.dart";
import "package:jwt_decoder/jwt_decoder.dart";
import "package:shared_preferences/shared_preferences.dart";

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const HomePage(),
      theme: ThemeData(useMaterial3: true),
      debugShowCheckedModeBanner: false,
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  HomePageState createState() => HomePageState();
}

class HomePageState extends State<HomePage> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback(
      (Duration timeStamp) async {
        await SharedPrefSingleton.instance.initSharedPreferences();
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: ElevatedButton(
            onPressed: fun,
            child: const Text("Check JWT Token"),
          ),
        ),
      ),
    );
  }

  Future<void> fun() async {
    // Not Expired Token
    // const String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjk5OTk5OTk5OTl9.Vg30C57s3l90JNap_VgMhKZjfc-p7SoBXaSAy8c28HA";

    // Expired Token
    const String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjEyMzQ1Njc4OTB9.Ev7tjNe1-zHZvSeoeEplJ1_xxfWLawVbp_EJXAsdzJU";

    final bool expired = JwtDecoder.isExpired(token);
    log("is token expired: $expired");

    await SharedPrefSingleton.instance.setToken(value: expired ? "New" : token);

    final String getCurrentToken = SharedPrefSingleton.instance.getToken();
    log("CurrentToken: $getCurrentToken");

    return Future<void>.value();
  }
}

class SharedPrefSingleton {
  SharedPrefSingleton._();
  static final SharedPrefSingleton instance = SharedPrefSingleton._();

  SharedPreferences? preferences;

  Future<void> initSharedPreferences() async {
    preferences = await SharedPreferences.getInstance();
    log("Loaded and parsed the SharedPreferences for this app from disk.");
    return Future<void>.value();
  }

  Future<bool> setToken({required String value}) async {
    final bool isSaved = await preferences?.setString("jwtKey", value) ?? false;
    log("Token Saved: ${isSaved ? "Successfully" : "Unsuccessfully"}");
    return Future<bool>.value(isSaved);
  }

  String getToken() {
    final String value = preferences?.getString("jwtKey") ?? "";
    log("Token value: $value");
    return value;
  }
}
hlswsv35

hlswsv352#

我想你可以用其他方法更好地处理这种情况,但是,如果你想根据验证时间在本地使令牌无效,你可以这样做:

void saveAccessToken(String token) async {
  final prefs = await SharedPreferences.getInstance();
  final now = DateTime.now();

  await prefs.setString('access_token', token);
  await prefs.setString('token_timestamp', now.toIso8601String());
}

Future<String?> getAccessToken() async {
  final prefs = await SharedPreferences.getInstance();
  final token = prefs.getString('access_token');
  final tokenTimestamp = prefs.getString('token_timestamp');

  if (token != null && tokenTimestamp != null) {
    final timestamp = DateTime.parse(tokenTimestamp);
    final currentTime = DateTime.now();
    final tokenDuration = currentTime.difference(timestamp);

    const Duration tokenExpirationDuration = Duration(hours: 1);

    if (tokenDuration <= tokenExpirationDuration) {
      return token;
    } else {
      await clearAccessToken();

      return null;
    }
  }

  return null;
}
1qczuiv0

1qczuiv03#

Timer timer = Timer.periodic(const Duration(hour: 1), (Timer timer) {
  //Clear Shared preference here
});

你可以用这个清除。但对于背景情况,它有一定的局限性。

相关问题