• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

flutter-登录token本地存储(shared_preferences)、路由拦截

武飞扬头像
jszlittlecat_720
帮助1

App一般都会遇到这样的需求:没有登录则跳转登录页面,登录了则跳转至指定页面。

思路:

1.登录之后存储token。

2.路由拦截,没有登录则跳转至登录页面,登录了则跳转至指定页面。

步骤:

一:首先在pubspec.yaml中添加shared_preferences依赖库

shared_preferences: ^2.0.17

整个pubspec.yaml如下所示:

  1.  
    name: flutter_doctor_app
  2.  
    description: A new Flutter application.
  3.  
     
  4.  
    # The following line prevents the package from being accidentally published to
  5.  
    # pub.dev using `pub publish`. This is preferred for private packages.
  6.  
    publish_to: 'none' # Remove this line if you wish to publish to pub.dev
  7.  
     
  8.  
    # The following defines the version and build number for your application.
  9.  
    # A version number is three numbers separated by dots, like 1.2.43
  10.  
    # followed by an optional build number separated by a .
  11.  
    # Both the version and the builder number may be overridden in flutter
  12.  
    # build by specifying --build-name and --build-number, respectively.
  13.  
    # In Android, build-name is used as versionName while build-number used as versionCode.
  14.  
    # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
  15.  
    # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
  16.  
    # Read more about iOS versioning at
  17.  
    # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
  18.  
    version: 1.0.0 1
  19.  
     
  20.  
    environment:
  21.  
    sdk: ">=2.19.2 <3.0.0"
  22.  
     
  23.  
    dependencies:
  24.  
    flutter:
  25.  
    sdk: flutter
  26.  
     
  27.  
     
  28.  
    # The following adds the Cupertino Icons font to your application.
  29.  
    # Use with the CupertinoIcons class for iOS style icons.
  30.  
    cupertino_icons: ^1.0.2
  31.  
     
  32.  
    dev_dependencies:
  33.  
    flutter_test:
  34.  
    sdk: flutter
  35.  
    shared_preferences: ^2.0.17
  36.  
     
  37.  
    # For information on the generic Dart part of this file, see the
  38.  
    # following page: https://dart.dev/tools/pub/pubspec
  39.  
     
  40.  
    # The following section is specific to Flutter.
  41.  
    flutter:
  42.  
     
  43.  
    # The following line ensures that the Material Icons font is
  44.  
    # included with your application, so that you can use the icons in
  45.  
    # the material Icons class.
  46.  
    uses-material-design: true
  47.  
     
  48.  
    # To add assets to your application, add an assets section, like this:
  49.  
    assets:
  50.  
    - images/info_image_portrait.png
  51.  
    - images/nav_icon_back.png
  52.  
    - images/logo.png
  53.  
    - images/passwordinvisible.png
  54.  
    - images/passwordvisible.png
  55.  
    - images/weixin_icon.png
  56.  
    # - images/a_dot_ham.jpeg
  57.  
     
  58.  
    # An image asset can refer to one or more resolution-specific "variants", see
  59.  
    # https://flutter.dev/assets-and-images/#resolution-aware.
  60.  
     
  61.  
    # For details regarding adding assets from package dependencies, see
  62.  
    # https://flutter.dev/assets-and-images/#from-packages
  63.  
     
  64.  
    # To add custom fonts to your application, add a fonts section here,
  65.  
    # in this "flutter" section. Each entry in this list should have a
  66.  
    # "family" key with the font family name, and a "fonts" key with a
  67.  
    # list giving the asset and other descriptors for the font. For
  68.  
    # example:
  69.  
    # fonts:
  70.  
    # - family: Schyler
  71.  
    # fonts:
  72.  
    # - asset: fonts/Schyler-Regular.ttf
  73.  
    # - asset: fonts/Schyler-Italic.ttf
  74.  
    # style: italic
  75.  
    # - family: Trajan Pro
  76.  
    # fonts:
  77.  
    # - asset: fonts/TrajanPro.ttf
  78.  
    # - asset: fonts/TrajanPro_Bold.ttf
  79.  
    # weight: 700
  80.  
    #
  81.  
    # For details regarding fonts from package dependencies,
  82.  
    # see https://flutter.dev/custom-fonts/#from-packages
学新通

二.在lib目录下创建common文件夹,创建LoginPrefs.dart文件

LoginPrefs.dart内容如下:

  1.  
    import 'package:flutter/cupertino.dart';
  2.  
    import 'package:shared_preferences/shared_preferences.dart';
  3.  
    class LoginPrefs{
  4.  
    static const String USER_NAME="USER_NAME";//用户名
  5.  
    static const String TOKEN="TOKEN";//token
  6.  
    static late SharedPreferences _prefs;//延迟初始化
  7.  
    static Future<String> init() async {
  8.  
    WidgetsFlutterBinding.ensureInitialized();
  9.  
    _prefs = await SharedPreferences.getInstance();
  10.  
    return 'ok';
  11.  
    }
  12.  
    static void saveUserName(String userName) {
  13.  
    _prefs.setString(USER_NAME, userName);
  14.  
    }
  15.  
    static String? getUserName() {
  16.  
    return _prefs.getString(USER_NAME);
  17.  
    }
  18.  
    static void saveToken(String token){
  19.  
    _prefs.setString(TOKEN, token);
  20.  
    }
  21.  
    static String? getToken() {
  22.  
    return _prefs.getString(TOKEN);
  23.  
    }
  24.  
    static void removeUserName() {
  25.  
    _prefs.remove(USER_NAME);
  26.  
    }
  27.  
    static void removeToken() {
  28.  
    _prefs.remove(TOKEN);
  29.  
    }
  30.  
    static void clearLogin(){
  31.  
    _prefs.clear();
  32.  
    }
  33.  
    }
学新通

三.在lib目录的common文件夹下创建MyRoutes.dart文件

MyRoutes.dart内容如下:

  1.  
    //配置路由
  2.  
     
  3.  
    import 'package:flutter/material.dart';
  4.  
    import 'package:flutter_doctor_app/common/LoginPrefs.dart';
  5.  
    import '../login.dart';
  6.  
    import '../main.dart';
  7.  
     
  8.  
    /*
  9.  
    * 这个方法是固定写法,功能就像是一个拦截器。
  10.  
    */
  11.  
    Route<dynamic>? onGenerateRoute(RouteSettings settings) {
  12.  
    Map<String, Widget> routes = {
  13.  
    'home': MyHomePage(), //定义app路径
  14.  
    'login': LoginPage(), //定义login路径
  15.  
    };
  16.  
     
  17.  
    String routerName = routeBeforeHook(settings);
  18.  
    bool mathMap = false;
  19.  
    Route<dynamic>? mathWidget;
  20.  
    routes.forEach((key, v) {
  21.  
    if (key == routerName) {
  22.  
    mathMap = true;
  23.  
    mathWidget = MaterialPageRoute(builder: (BuildContext context) => v);
  24.  
    }
  25.  
    });
  26.  
     
  27.  
    if (mathMap) {
  28.  
    return mathWidget;
  29.  
    }
  30.  
    return MaterialPageRoute(
  31.  
    builder: (BuildContext context) => Container(
  32.  
    child: Text('404'),
  33.  
    ));
  34.  
    }
  35.  
     
  36.  
    String routeBeforeHook(RouteSettings settings) {
  37.  
    if(checkToken()==false){
  38.  
    return 'login';
  39.  
    }else{
  40.  
    return settings.name!;
  41.  
    }
  42.  
    }
  43.  
    bool checkToken() {
  44.  
    String token = LoginPrefs.getToken()??'';
  45.  
    if ('' != token) return true;
  46.  
    return false;
  47.  
    }
学新通

四.在main.dart中修改main方法如下所示:

  1.  
    void main() async{
  2.  
    String value= await LoginPrefs.init();// await 关键字必须用在异步方法中 await等待异步方法执行完毕 异步方法必须用变量接收
  3.  
    if('ok'==value){
  4.  
    runApp(MyApp());
  5.  
    }
  6.  
    }

shared_preferences的初始化过程是个耗时的操作,所以要放在异步方法中,LoginPrefs.dart的init()方法

static Future<String> init() async {

WidgetsFlutterBinding.ensureInitialized();

_prefs = await SharedPreferences.getInstance();

return 'ok';

}

我们需要的是必须要等待初始化完成,我们才可以进行其它操作,所以前面需要await修饰,等待异步初始化完成,而若使用await关键字则必须在异步方法中,所以,修改main方法由async修饰。

void main() async{

String value= await LoginPrefs.init();// await 关键字必须用在异步方法中 await等待异步方法执行完毕 异步方法必须用变量接收

if('ok'==value){

runApp(MyApp());

}

}

五.main.dart添加路由拦截

  1.  
    class MyApp extends StatelessWidget {
  2.  
    // This widget is the root of your application.
  3.  
     
  4.  
    @override
  5.  
    Widget build(BuildContext context) {
  6.  
    return MaterialApp(
  7.  
    title: 'Flutter Demo',
  8.  
    debugShowCheckedModeBanner: false,
  9.  
    //去除右上角的Debug标签
  10.  
    theme: ThemeData(
  11.  
    // This is the theme of your application.
  12.  
    //
  13.  
    // Try running your application with "flutter run". You'll see the
  14.  
    // application has a blue toolbar. Then, without quitting the app, try
  15.  
    // changing the primarySwatch below to Colors.green and then invoke
  16.  
    // "hot reload" (press "r" in the console where you ran "flutter run",
  17.  
    // or simply save your changes to "hot reload" in a Flutter IDE).
  18.  
    // Notice that the counter didn't reset back to zero; the application
  19.  
    // is not restarted.
  20.  
    primarySwatch: createMaterialColor(Color(0xFF009999)),
  21.  
    // This makes the visual density adapt to the platform that you run
  22.  
    // the app on. For desktop platforms, the controls will be smaller and
  23.  
    // closer together (more dense) than on mobile platforms.
  24.  
    visualDensity: VisualDensity.adaptivePlatformDensity,
  25.  
    ),
  26.  
    initialRoute: "home",
  27.  
    onGenerateRoute: onGenerateRoute,
  28.  
    //注册路由表
  29.  
    );
  30.  
    }
  31.  
    }
学新通

onGenerateRoute: onGenerateRoute

路由拦截

六.login.dart中点击登录按钮执行的方法:

  1.  
    void onLoginClick() async {
  2.  
    print("登录");
  3.  
    setState(() {
  4.  
    // 当所有编辑框都失去焦点时键盘就会收起
  5.  
    _uNameFocusNode.unfocus();
  6.  
    _uPassFocusNode.unfocus();
  7.  
    LoginPrefs.saveToken(_uNameController.text);//保存token (我这里保存的输入框中输入的值)
  8.  
    Navigator.of(context).pop();//登录页消失
  9.  
    Navigator.pushNamed(context, 'home');//跳转至首页
  10.  
    });
  11.  
    }

至此,就完成了路由拦截功能,没有登录则跳转登录页面,登录了则跳转至指定页面。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfhgkfg
系列文章
更多 icon
同类精品
更多 icon
继续加载