flutter:如何使用共享首选项来保持用户登录状态

时间:2021-05-30 13:22:06

标签: flutter dart

我想在用户成功登录flutter后保持用户登录状态。我正在使用 REST API 来检索用户的用户名和密码。但我想保存这些详细信息,以便用户可以保持登录状态。我目前的情况是我可以成功登录用户,但是当我重新启动应用程序时,我必须再次登录,因此我需要将用户的详细信息保存在共享首选项,以便用户可以在整个会话中保持登录状态,直到注销。但我无法这样做,所以请帮助我。提前致谢

登录.dart

Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color.fromRGBO(3, 9, 23, 1),
      body: Container(
          padding: EdgeInsets.only(
            top: 100,
            right: 30,
            left: 30,
          ),
          child: SingleChildScrollView(
            child: Form(
              key: _formKey,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  FadeAnimation(
                      1.2,
                      Container(
                        padding: EdgeInsets.all(70.0),
                        margin: EdgeInsets.only(bottom: 50.0),
                        decoration: BoxDecoration(
                            image: DecorationImage(
                                image: AssetImage(
                                    'assets/images/trakinglogo.png'))),
                      )),
                  SizedBox(
                    height: 30,
                  ),
                  FadeAnimation(
                      1.5,
                      Container(
                        padding: EdgeInsets.all(10),
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(10),
                            color: Colors.white),
                        child: Column(
                          children: <Widget>[
                            Container(
                              decoration: BoxDecoration(
                                  border: Border(
                                      bottom:
                                          BorderSide(color: Colors.grey[300]))),
                              child: TextFormField(
                                controller: _emailController,
                                onFieldSubmitted: (_) =>
                                    FocusScope.of(context).nextFocus(),
                                textInputAction: TextInputAction.done,
                                validator: (value) {
                                  if (value.isEmpty) {
                                    return 'Email is required';
                                  }
                                  return null;
                                },
                                decoration: InputDecoration(
                                    border: InputBorder.none,
                                    hintStyle: TextStyle(
                                        color: Colors.grey.withOpacity(.8)),
                                    hintText: "Votre adresse mail"),
                              ),
                            ),
                            Container(
                              decoration: BoxDecoration(),
                              child: TextFormField(
                                controller: _passwordController,
                                validator: (value) {
                                  if (value.isEmpty) {
                                    return 'Password is required';
                                  }
                                  return null;
                                },
                                obscureText: _isHidden,
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                  hintStyle: TextStyle(
                                      color: Colors.grey.withOpacity(.8)),
                                  hintText: "Mot de passe",
                                  suffix: InkWell(
                                      onTap: _togglePasswordView,
                                      child: Icon(
                                        _isHidden
                                            ? (CommunityMaterialIcons
                                                .eye_outline)
                                            : (CommunityMaterialIcons.eye_off),
                                        color: Color(0xFF939394),
                      
                  SizedBox(
                    height: 40,
                  ),
                  FadeAnimation(
                      1.8,
                      Center(
                          child: Column(
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              Container(
                                child: RaisedButton(
                                  textColor: Colors.white,
                                  color: kPrimaryColor,
                                  child: Text("Se connecter"),
                                  onPressed: () async {
                                    if (_formKey.currentState.validate()) {
                                      showDialog(
                                          context: context,
                                          builder: (BuildContext context) {
                                            return Center(
                                              child:
                                                  CircularProgressIndicator(),
                                            );
                                          });
                                      await loginUser();
                                    }
                                    /*  Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                          builder: (context) => MyWidget()),
                                    );*/
                                    // Navigator.pushNamed(context, 'Mywidget');
                                  },
                                  shape: new RoundedRectangleBorder(
                                    borderRadius:
                                        new BorderRadius.circular(30.0),
                                  ),
                                ),
                                width: 250,
                                padding: EdgeInsets.all(15),
                              )
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              AlreadyHaveAnAccountCheck(
                                press: () {
                                  Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                      builder: (context) {
                                        return SignUp();

 void loginUser() async {
    // if (_formKey.currentState.validate()) {
    setState(() {
      _isLoading = true;
    });
    String email = _emailController.text;
    String password = _passwordController.text;

    authentication.login(email, password).then((user) {
      if (user != null)
        Navigator.push(
            context, MaterialPageRoute(builder: (context) => MyWidget()));
    }).catchError((error) {
      ScaffoldMessenger.of(context)
          .showSnackBar(SnackBar(content: Text(error.toString())));
    });

    setState(() {
      _isLoading = false;
    });
  }

这是登录功能:

Future<User> login(String email, String password) async {
  await checkInternet();

  Map<String, String> headers = {
    'Content-type': 'application/json',
    'Accept': 'application/json',
  };
  Map<String, String> body = {'email': email, 'password': password};

  var response = await http.post(Uri.parse(ApiUtil.AUTH_LOGIN),
      headers: headers, body: jsonEncode(body));
  switch (response.statusCode) {
    case 200:
      var body = jsonDecode(response.body);
      var data = body['user'];
      User user = User.fromJson(data);
      Track track = Track.fromJson(body);

      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']));
        String user = localStorage.getString('user');

      }
      return user;
    case 500:
      throw ('Erreur serveur');
      break;

    case 400:
      throw LoginFailed();
    default:
      throw ('connection timeout');
      break;
  }
}

2 个答案:

答案 0 :(得分:0)

创建一个类 AppSharedPreference 并在该类中创建这些方法:

User 是您的 modal 类。

保存用户:

static saveUser(String key, User value) async {
    final prefs = await SharedPreferences.getInstance();
    //We cannot save custom objects.
    //So json.encode is used to convert User Object to Json a string.
    prefs.setString(key, json.encode(value));
  }

获取用户:

static readUser(String key) async {
    final prefs = await SharedPreferences.getInstance();
    //json.decode to convert json string back to Json Object
    return json.decode(prefs.getString(key));
  }

确保您的模态 User 类包含 toJson 方法:

Map<String, String> toJson() => {
        'id': Id,
        'address': address,
        'phone': phone,
        // rest of your attributes...
      };

调用 saveUser 方法:

await AppSharedPreference.saveUser('your_key', user);

调用 readUser 方法: (确保您的模态 User 类包含 fromJson 方法)

User user = User.fromJson(await AppSharedPreference.readUser('your_key'));

然后您可以检查 user 是否为 null。如果是 null,则表示没有数据且 user 未登录。

如果您想要 logout 用户,您可以创建一个方法从 SharedPreference 中删除用户:

删除用户:

static removeUser(String key) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.remove(key);
}

调用 removeUser 方法:

await AppSharedPreference.removeUser('your_key');

答案 1 :(得分:0)

您必须在应用程序启动时检查 sharedPreference 中是否有数据,然后根据该数据重定向用户。一个例子是在闪屏中实现这个

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'home_page.dart';
import 'login_page.dart';

class SplashScreen extends StatefulWidget {
  static const String splashRoute = '/';

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

class _SplashScreenState extends State<SplashScreen> {
  void timeToShowSplashScreenOnScreen() async {
    Timer(Duration(seconds: 3), () async {
      if (!mounted) return;
      SharedPreferences _prefs = await SharedPreferences.getInstance();
      bool isLoggedIn = _prefs.getBool("loggedIn");
      if (isLoggedIn != null && isLoggedIn) {
        Navigator.of(context).pushNamedAndRemoveUntil(HomePage.homePageRoute, (route) => false);
      } else {
        Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.loginRoute, (route) => false);
      }
    });
  }

  @override
  void initState() {
    super.initState();
    timeToShowSplashScreenOnScreen();
  }

  @override
  Widget build(BuildContext context) {
    double _width = MediaQuery.of(context).size.width;
    double _height = MediaQuery.of(context).size.height;
    return Scaffold(
      body: Container(
        width: _width,
        height: _height,
        child: Stack(
          children: [
            // Your UI for splash screen
          ],
        ),
      ),
    );
  }
}

这个例子使用存储在 prefs 中的布尔值,但你也可以用字符串做类似的事情。