如何存储用户ID或“密钥"?登录并从Flutter应用程序中的任何位置访问后? [英] How to store a User id or "key" after login and access from anywhere in Flutter app?

查看:66
本文介绍了如何存储用户ID或“密钥"?登录并从Flutter应用程序中的任何位置访问后?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试确定登录后存储和访问Flutter应用程序的User对象的最佳方法.到目前为止,还没有真正的身份验证.因此,当用户"登录它只是检查json文件中的虚拟用户名和密码.我唯一想知道的是从应用程序中的任何位置存储和访问我的用户ID的适当方法是什么?每次屏幕更改时,我都一直将其作为路由参数传递,但这似乎有点过头了.最合适的方法是什么?只需创建一个globals.dart文件并将用户ID添加为变量?

I am trying to determine the best way to store and access my Flutter app's User object after a login. There is no real authentication as of right now. So when the "user" logs in it just checks a json file for a dummy username and password. The only thing I want to know is what is the appropriate way to store and access my User id from anywhere in the app? I have been passing it as a route parameter every time the screen changes but that seems like overkill. What is the most appropriate way to do this? Just create a globals.dart file and add the user id as a variable?

json中的用户示例:

Example of User in json:

{
    "id" : 5,
    "fName" : "John",
    "lName" : "Doe",
    "position" : "Software Developer",
    "username" : "jdoe",
    "password" : "jdoepass",
    "imageUrl": "assets/images/profile_pictures/profilePicture.png",
    "email" : "jdoe@onepartner.com",
    "location" : "Big Software Company"
}

Login.dart:

Login.dart:

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../utils/opWidgets.dart';
import '../utils/fetchJson.dart';
import '../../entities/User.dart';

/* Description: Login screen widget and functions to handle fetching user json */

class LoginPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _LoginPageState();
  }
}

class _LoginPageState extends State<LoginPage> {
  List<User> _userList = []; //used to represent the list items in the UI
  final userTxtController = TextEditingController();
  final passTxtController = TextEditingController();
  User _currentUser;
  bool _invalidUserMsgVisible = false;

  @override
  initState() {
    //initializes data before build() is called
    //Use this method to initialize data that will be displayed
    //initialize list items using function that fetches/converts json
    fetchUsers().then((value) {
      setState(() {
        _userList.addAll(value);
      });
    });
    super.initState();
  }

  @override
  void dispose() {
    //releases memory
    userTxtController.dispose();
    passTxtController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      body: GestureDetector(
        //Makes the keyboard collapse when the scaffold body is tapped
        onTap: () => FocusScope.of(context).unfocus(),
        child: _layoutDetails(),
      ),
    );
  }

  //This widget determines the layout of the widgets _logo() and _loginForm() based on the screen's orientation
  Widget _layoutDetails() {
    Orientation orientation = MediaQuery.of(context).orientation;

    if (orientation == Orientation.portrait) {
      return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          _logo(),
          _loginForm(),
        ],
      );
    } else {
      return Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          _logo(),
          Container(
            width: MediaQuery.of(context).size.width / 1.8,
            height: MediaQuery.of(context).size.height,
            child: _loginForm(),
          ),
        ],
      );
    }
  }

  Widget _logo() {
    return Container(
      width: 225,
      child: Image.asset('assets/images/logos/OPNewLogo.png'),
    );
  }

  Widget _loginForm() {
    return Container(
      width: double.infinity,
      padding: EdgeInsets.all(20),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Visibility(
            visible: _invalidUserMsgVisible,
            child: Text(
              'Username or password is invalid',
              style: GoogleFonts.montserrat(color: Colors.red, fontSize: 14),
            ),
          ),
          SizedBox(height: 5),
          Container(
            //margin: EdgeInsets.symmetric(horizontal: 10),
            width: 500,
            child: opTextField('Username', false, userTxtController),
          ),
          SizedBox(height: 20),
          Container(
            //margin: EdgeInsets.symmetric(horizontal: 10),
            width: 500,
            child: opTextField('Password', true, passTxtController),
          ),
          SizedBox(height: 20),
          Container(
            width: 500,
            height: 40,
            padding: EdgeInsets.symmetric(horizontal: 8),
            child: ElevatedButton(
              onPressed: () => _verifyLogin(
                userTxtController.text.toString().trim(),
                passTxtController.text.toString(),
              ),
              child: Text(
                'LOGIN',
                style: GoogleFonts.montserrat(
                  fontSize: 16,
                  letterSpacing: 1.5,
                  color: Colors.white,
                  fontWeight: FontWeight.w500,
                ),
              ),
              style: ElevatedButton.styleFrom(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20),
                ),
                primary: Theme.of(context).accentColor,
                elevation: 3,
              ),
            ),
          ),
          SizedBox(height: 5),
          Container(
            width: 500,
            height: 40,
            padding: EdgeInsets.symmetric(horizontal: 8),
            child: ElevatedButton(
              onPressed: () => {
                Navigator.pop(context),
              },
              child: Text(
                'REGISTER',
                style: TextStyle(
                    fontSize: 16,
                    letterSpacing: 2.2,
                    color: Theme.of(context).shadowColor,
                    fontWeight: FontWeight.w500),
              ),
              style: ElevatedButton.styleFrom(
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20),
                  side: BorderSide(
                    color: Theme.of(context).primaryColorDark,
                  ),
                ),
                primary: Colors.white,
              ),
            ),
          ),
          Container(
            child: TextButton(
              autofocus: false,
              clipBehavior: Clip.none,
              child: Text(
                'Forgot Password',
                style: GoogleFonts.montserrat(
                  fontSize: 15,
                  color: Theme.of(context).shadowColor,
                  decoration: TextDecoration.underline,
                ),
              ),
              onPressed: () =>
                  Navigator.pushNamed(context, resetPasswordPageRoute),
            ),
          ),
        ],
      ),
    );
  }

  //Function to check the username and password input against the list of user objects
  void _verifyLogin(String username, String password) {
    bool _validUser = false;

    //Loop through fetched user objects and check for a match
    for (var user in _userList) {
      if (username == user.username && password == user.password) {
        _validUser = true;
        _currentUser = user; //Set the current user object
        break;
      }
    }
    //If a valid user was found, pop login screen and push home screen
    if (_validUser) {
      Navigator.popAndPushNamed(
        context,
        homePageRoute,
        arguments:
            _currentUser, //Pass the current user object to the home screen
      );
    } else {
      //if no valid user was found, make error message text visible
      setState(() {
        _invalidUserMsgVisible = true;
      });
    }
  }
}

推荐答案

我想您最终将希望通过超时进行用户身份验证,因此需要一种方法来在用户超时时通知应用程序.一个很好的方法是使用 ChangeNotifierProvider -有很好的教程,例如简单的应用程序状态管理.使用此机制来共享您的状态是一个好主意,甚至在您需要通知之前.

I guess you will eventually want to have user authentication with timeout, so will need a way to notify the app when the user times out. A good way to do this is using ChangeNotifierProvider - there are good tutorials, e.g. Simple app state management. It is a good idea to use this mechanism to share your state, even before you need notifications.

这是示例代码:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

// User class
class User {
  final String username;
  User(this.username);
  String toString() => username;
}

// AuthService has all authentication logic, notifies listeners
class AuthService with ChangeNotifier {
  User _user;
  User get user => _user;

  Future<void> _authenticate(String email, String password,
      [String name]) async {
    // This is where you authenticate or register the user, and update the state
    _user = User("dummy");
    return Future<void>(() {});
  }

  Future<void> register(String name, String email, String password) async {
    return _authenticate(email, password, name);
  }

  Future<void> login(String email, String password) async {
    return _authenticate(email, password);
  }

  Future<void> logout() async {
    _user = null;
    notifyListeners();
    return Future<void>(() {});
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Put all your ChangeNotifierProviders above MaterialApp
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => AuthService(),
        ),
      ],
      child: MaterialApp(
        title: 'Test App',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: AuthTest(),
      ),
    );
  }
}

class AuthTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
        // Login user
        TextButton(
          child: Text("Login"),
          onPressed: () async {
            await Provider.of<AuthService>(context, listen: false)
                .login("email", "password");
          },
        ),
        // Logout user
        TextButton(
          child: Text("Logout"),
          onPressed: () async {
            await Provider.of<AuthService>(context, listen: false).logout();
          },
        ),
        // Child form
        TextButton(
          child: Text("Form"),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => AuthFormTest()),
            );
          },
        ),
      ]),
    );
  }
}

class AuthFormTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Get AuthService, will rebuild when it notifies listeners
    var authService = Provider.of<AuthService>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('User'),
      ),
      body: Center(child: Text('User: ${authService.user}')),
    );
  }
}

这篇关于如何存储用户ID或“密钥"?登录并从Flutter应用程序中的任何位置访问后?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆