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

如何用SharedPreferences存储Token?登录后Token未保存引发401问题

问题分析与修复方案

核心问题

  • 登录成功后未保存Token:你的登录方法在拿到200响应并解析User后,完全没有调用UtilSharedPreferences.setToken()将接口返回的Token存入本地,这直接导致后续API请求时无法获取有效Token,返回401。
  • 登录请求冗余携带旧Token:登录接口本身是用来获取新Token的,通常不需要在请求头中携带Authorization,但你当前代码里却带上了之前存储的旧Token(初始为空),虽然接口返回200,但这不符合接口设计逻辑。

修复步骤

1. 移除登录请求的冗余请求头

登录接口不需要携带认证信息,直接删除Authorization头:

var response = await http.post(
  Uri.parse('http://dev.api.app.masoemuniversity.ac.id/v1/login_mhs'),
  // 移除多余的Authorization头
  body: body,
);

2. 登录成功后添加Token保存逻辑

解析响应数据后,提取Token并调用工具类保存到SharedPreferences:

if (response.statusCode == 200) {
  var responseData = jsonDecode(response.body);
  // 注意:这里的字段名要和接口返回的Token字段完全一致,比如接口返回的是access_token就用这个
  String newToken = responseData['access_token'];
  // 保存Token到本地
  await UtilSharedPreferences.setToken(newToken);
  // 返回解析后的User对象
  return User.fromJson(responseData);
} else {
  return null;
}

3. 优化工具类的setToken方法(可选)

给setToken添加返回值,方便验证是否保存成功:

class UtilSharedPreferences {
  static Future<String> getToken() async {
    SharedPreferences _prefs = await SharedPreferences.getInstance();
    return _prefs.getString('access_token') ?? '';
  }

  static Future<bool> setToken(String value) async {
    SharedPreferences _prefs = await SharedPreferences.getInstance();
    return _prefs.setString('access_token', value);
  }
}

调用时可以打印验证:

bool saveSuccess = await UtilSharedPreferences.setToken(newToken);
print('Token保存状态:$saveSuccess');

完整修改后的登录代码

Future<User?> login(String nim, String password) async {
  try {
    var body = {
      'username': nim,
      'password': password,
    };
    var response = await http.post(
      Uri.parse('http://dev.api.app.masoemuniversity.ac.id/v1/login_mhs'),
      body: body,
    );
    print(response.statusCode);
    print(response.body);

    if (response.statusCode == 200) {
      var responseData = jsonDecode(response.body);
      String newToken = responseData['access_token'];
      await UtilSharedPreferences.setToken(newToken);
      return User.fromJson(responseData);
    } else {
      return null;
    }
  } catch (e) {
    print(e);
    return null;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:31:16