You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何将token、userId存入SharedPreferences并在其他页面读取使用

解决方案

1 修复userId存储失败问题

你当前存储失败的核心原因有两个:一是接口返回的userId可能为字符串类型,直接调用setInt会触发类型异常导致存储终止;二是Album类的fromJson方法字段映射完全不匹配接口返回结构,会触发解析异常。
修改登录接口请求的存储逻辑:

Future<Album> createAlbum(String employee_custom_id, String password) async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    final response = await http.post(
      Uri.parse('https://你的实际域名.com/api/auth/login'),
      headers: <String, String>{
        'Content-Type': 'application/json',
      },
      body: jsonEncode(<String, String>{
        'employee_custom_id': employee_custom_id,
        'password': password,
      }),
    );

    final data = json.decode(response.body);
    if (response.statusCode == 200) {
      // 存储token
      sharedPreferences.setString("token", data['token']);
      // 统一转成int类型再存储,避免接口返回字符串类型导致存储失败
      int userId = int.parse(data['userId'].toString());
      sharedPreferences.setInt("userId", userId);
      // 强制提交持久化(iOS端建议添加,安卓默认自动提交)
      await sharedPreferences.commit();
      log('存储成功:token=${data['token']}, userId=$userId');

      return Album.fromJson(data);
    } else {
      throw Exception('登录请求失败');
    }
}

同步修复Album类的字段映射:

class Album {
  final String token;
  final int userId;
  final String message;
  final String passwordChanged;

  Album({
    required this.token,
    required this.userId,
    required this.message,
    required this.passwordChanged,
  });

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      token: json['token'],
      userId: json['userId'],
      message: json['message'],
      passwordChanged: json['passwordChanged'],
    );
  }
}

2 登录页实现userId逻辑判断+Snackbar提示

修改登录按钮的onPressed逻辑,监听登录结果做对应提示:

onPressed: () {
  if(_emailController.text.isEmpty || _passwordController.text.isEmpty){
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('账号或密码不能为空'))
    );
    return;
  }
  setState(() {
    _futureAlbum = createAlbum(_emailController.text, _passwordController.text);
  });
  // 异步监听登录结果
  _futureAlbum?.then((album) {
    // 登录成功,用userId做判断逻辑
    if(album.userId > 0){
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('登录成功,欢迎用户${album.userId}'))
      );
      // 跳转列表页
      Navigator.push(context, MaterialPageRoute(builder: (context)=> const ListsPage()));
    }else{
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('账号异常,请联系管理员'))
      );
    }
  }).catchError((e){
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('登录失败:${e.toString()}'))
    );
  });
},

3 lists.dart页面读取存储的token和userId

只需要先初始化SharedPreferences实例,再通过key取值即可:

Future<List<ListAlbum>> listData() async {
  // 先获取SharedPreferences实例
  SharedPreferences sp = await SharedPreferences.getInstance();
  // 取值,空值返回null便于判断登录状态
  final String? token = sp.getString("token");
  final int? userId = sp.getInt("userId");
  
  // 未登录状态抛出异常后续自行处理
  if(token == null || userId == null){
    throw Exception('用户未登录,请先登录');
  }
  String url = 'https://你的实际域名.com/api/getOrganizationData?token=${token}';

  Dio dio = Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  // 接口需要传userId的话直接使用上面取到的userId变量即可
  final body = {'limit': 100, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);
    return response.data["data"]["data"]
        .map<ListAlbum>((json) => ListAlbum.fromJson(json))
        .toList();
  } else {
    throw Exception('请求数据失败');
  }
}

其他页面通用读取方式

任何需要使用token、userId的页面,都可以用如下方式直接读取:

SharedPreferences sp = await SharedPreferences.getInstance();
String? token = sp.getString("token");
int? userId = sp.getInt("userId");

退出登录时清除存储数据:

SharedPreferences sp = await SharedPreferences.getInstance();
sp.remove("token");
sp.remove("userId");
// 或直接清空所有存储 sp.clear();

内容的提问来源于stack exchange,提问作者Fozuda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 01:06:03