Flutter中利用SharedPreferences实现用户登录状态持久化的方法求助
Hey there! Let's get that login persistence sorted out for you. The core issue here is that while you're saving user data to SharedPreferences after a successful login, your app isn't checking that saved data when it starts up. Here's how to fix this step by step:
1. Check Login Status on App Startup
First, we need to verify if there's a saved user session when the app launches. Modify your main.dart to check SharedPreferences before deciding which screen to show:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'login.dart'; import 'my_widget.dart'; void main() async { // Required to use SharedPreferences before runApp() WidgetsFlutterBinding.ensureInitialized(); SharedPreferences prefs = await SharedPreferences.getInstance(); // Check if we have a saved user object String savedUser = prefs.getString('user'); runApp(MaterialApp( title: 'Your App', // Navigate to home if user exists, else login screen home: savedUser != null ? MyWidget() : Login(), debugShowCheckedModeBanner: false, )); }
2. Improve Login Success Navigation
Right now, you're using Navigator.push() which keeps the login screen in the navigation stack. Use pushReplacement() instead so users can't navigate back to the login screen after logging in:
Update the login success logic in your loginUser() method:
authentication.login(email, password).then((user) { if (user != null) { Navigator.pushReplacement( // Use pushReplacement here context, MaterialPageRoute(builder: (context) => MyWidget()) ); } }).catchError((error) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text(error.toString()))); });
3. Add a Logout Functionality
To let users properly end their session, add a logout method that clears saved data from SharedPreferences and navigates back to the login screen. For example, in your MyWidget:
void logout() async { SharedPreferences prefs = await SharedPreferences.getInstance(); // Clear all saved session data (or remove specific keys if needed) await prefs.remove('user'); await prefs.remove('access_token'); await prefs.remove('id'); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => Login()) ); }
You can call this method from a button in MyWidget:
ElevatedButton( onPressed: logout, child: Text('Se déconnecter'), )
4. Verify SharedPreferences Saving
Double-check that your login function is correctly saving the user data. Add a quick print statement to confirm the data is being stored:
In your login API function:
if (body['code'] == 0) { SharedPreferences localStorage = await SharedPreferences.getInstance(); localStorage.setInt('id', body['user']['id']); localStorage.setString('adress', body['user']['adress']); localStorage.setString('phone', body['user']['phone']); localStorage.setString('access_token', body['access_token']); localStorage.setString('user', json.encode(body['user'])); // Verify the save String savedUser = localStorage.getString('user'); print('Saved User Data: $savedUser'); // Check console for this output return user; }
Key Notes
- Make sure your
User.fromJsonmethod correctly parses the saved JSON string if you need to reconstruct the User object later. - Always use
WidgetsFlutterBinding.ensureInitialized()when accessingSharedPreferencesbeforerunApp(). - For added security, consider encrypting sensitive data like access tokens before storing them in
SharedPreferences.
Give these changes a go, and your users should stay logged in across app restarts until they choose to log out. Let me know if you hit any snags along the way!
内容的提问来源于stack exchange,提问作者lucky

