如何在Dio函数中从Flutter Secure Storage读取Token
问题解决:从Flutter Secure Storage获取Token并传入Dio请求头
你的代码问题出在异步操作的执行顺序上:调用readSecureData后用then处理结果是异步行为,代码会直接跳过这部分继续执行创建headers和Dio实例的逻辑,此时token还是初始的空字符串,自然无法正确传入请求头。
推荐方案:使用Dio拦截器动态添加Token
拦截器可以在每次发起请求前自动获取最新的Token并注入请求头,还能方便后续处理Token过期刷新的场景,代码修改如下:
- 同步创建基础Dio实例,通过拦截器动态注入Token:
static Dio? dio; Dio getDio() { if (dio == null) { Duration timeOut = const Duration(seconds: 4); BaseOptions options = BaseOptions( baseUrl: ApiConst.apiBaseUrl, headers: { 'Accept': ApiConst.applicationJson, 'Content-Type': ApiConst.applicationJson, }, connectTimeout: timeOut, receiveTimeout: timeOut, ); dio = Dio(options); // 添加请求拦截器,每次请求前读取Token dio!.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) async { String? token = await SecureStorage().readSecureData("login_token"); if (token != null) { options.headers['Authorization'] = "Bearer $token"; } return handler.next(options); }, )); } return dio!; }
这种方式会在每次请求前异步读取最新Token,既保证了请求头的正确性,也能适配Token中途更新的场景。
备选方案:将getDio改为异步函数
如果不需要拦截器,也可以直接修改getDio为异步函数,等待Token读取完成后再创建Dio实例:
static Dio? dio; Future<Dio> getDio() async { if (dio == null) { // 等待Token读取完成 String? token = await SecureStorage().readSecureData("login_token"); var headers = { 'Accept': ApiConst.applicationJson, 'Content-Type': ApiConst.applicationJson, 'Authorization': "Bearer ${token ?? ''}" }; Duration timeOut = const Duration(seconds: 4); BaseOptions options = BaseOptions( baseUrl: ApiConst.apiBaseUrl, headers: headers, connectTimeout: timeOut, receiveTimeout: timeOut, ); dio = Dio(options); } return dio!; }
注意:这种方式需要在调用getDio的地方使用await,且Dio实例创建后Token不会自动更新,仅适合Token不会中途变化的场景。
内容的提问来源于stack exchange,提问作者Shady Hesham
相关产品推荐
相关产品推荐

