Home > OS >  How to cache authorization Data(access_token)?
How to cache authorization Data(access_token)?

Time:12-14

I have macOS app and I want to cache data when user sign in or sign up. I have access_token and refresh_token.

And when user launch Mac OS app again, I want to make user won't sign in again and immediately transfer to MainWidget()

For storing access_token and refresh_token, I use shared_preferences

This is my PreferencesProvider:

class PreferencesProvider {
  static PreferencesProvider? _instance;
  SharedPreferences? _preferences;

  factory PreferencesProvider() {
    _instance ??= PreferencesProvider._();
    return _instance!;
  }

  PreferencesProvider._() {
    _initPreferences();
  }

  Future<void> _initPreferences() async {
    _preferences = await SharedPreferences.getInstance();
  }

  Future<void> setAccess(String value) async {
    await _initPreferences();
    await _preferences!.setString("ACCESS_TOKEN", value);
  }
  
  Future<String?> getAccess() async {
    await _initPreferences();
    return _preferences!.getString("ACCESS_TOKEN");
  }

  Future<void> clearAccess() async {
    await _initPreferences();
    await _preferences!.remove("ACCESS_TOKEN");
  }

  Future<void> setRefresh(String value) async {
    await _initPreferences();
    await _preferences!.setString("REFRESH_TOKEN", value);
  }

  Future<String?> getRefresh() async {
    await _initPreferences();
    return _preferences!.getString("REFRESH_TOKEN");
  }
}

And this is my authorization cubit when I sign in or Sign up(if authorization is successful):

if (data['success']) {
        await _preference.clearAccess();
        PreferencesProvider()
          ..setUserId(data['userId'])
          ..setAccess(data['accessToken'])
          ..setRefresh(data['refreshToken']);
        _apiProvider.setToken(data["accessToken"]);
}

And this is what I show in Main App: home: const StartScreen(),

When I launched my Mac OS app and if I signed in then I want to show home: MainWidget()

CodePudding user response:

As the home: of your MaterialApp, always assign an intermediate screen[whether or not you are logged in], in this screen we will check if the user is logged in or not and redirect him to respective screens. Let's say the intermediate screen is SplashScreen which could look something like this:

class SplashScreen extends StatefulWidget {
  const SplashScreen({Key? key}) : super(key: key);

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  Future<bool> _checkLoginStatus() async {
    try {
      //check whether we have access and refresh tokens here (maybe also perform
      // a network request to check if the tokens are still valid) and
      // based on that, return true or false
    } catch (e) {
      return false;
    }
  }

  @override
  void initState() {
    _checkLoginStatus().then((value) {
      if (value == true) {
        //navigate the user to MainWidget()
      } else {
        //navigate the user to StartScreen()
      }
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: CircularProgressIndicator()),
    );
  }
}

PS: if you intend to save your tokens locally, consider using packages like flutter_secure_storage or hive so that you can encrypt your data while saving.

  • Related