flutter 自动刷新token

创建一个拦截器
重写onRequest方法,在每次请求前header中加入token
重写onError方法,如果errorCode401表示token过期,这时需要重新调用登录接口获取新的token,并将得到的新token写入该次请求,重新发送这次请求,然后将创建好的拦截器加入到dio的拦截器数组中,_dio.interceptors.add()

import 'dart:async';
import 'dart:io';

import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:fm_location/api/api.dart';
import 'package:fm_location/api/auth.dart';
import 'package:fm_location/api/dio_new.dart';
import 'package:fm_location/base/app_config.dart';
import 'package:fm_location/utils/preference_utils.dart';

import 'my_cookie.dart';

class RefreshTokenInterceptor extends Interceptor {
  @override
  void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
    String token = PreferenceUtils().getString(Authorization_key);

    if (token != '') {
      options.headers[Authorization_key] = 'Bearer ' + token;
      options.headers['language'] = 'zh_CN';
    }
    super.onRequest(options, handler);
  }

  @override
  void onResponse(Response response, ResponseInterceptorHandler handler) {
    super.onResponse(response, handler);
  }

  @override
  void onError(DioError err, ErrorInterceptorHandler handler) async {
    // token过期
    if (err.response != null && err.response!.statusCode == 401) {
      String? token = await getToken(handler);
      if (token == null) {
        handler.next(err);
        return;
      }
      Auth.token = token;
      RequestOptions? request = err.response?.requestOptions;
      request!.headers[Authorization_key] = 'Bearer ' + token;
      try {
        Dio _dio = Dio();
        _dio.options.baseUrl = Api.baseUrl;
        Response response = await _dio.request(request.path,
            data: request.data,
            options: Options(
                method: request.method,
                headers: request.headers,
                contentType: 'application/json'),
            queryParameters: request.queryParameters,
            cancelToken: request.cancelToken,
            onReceiveProgress: request.onReceiveProgress);
        handler.resolve(response);
      } on DioError catch (e) {
        handler.next(e);
        super.onError(err, handler);
      }
    }
  }

  Future getToken(ErrorInterceptorHandler handler) async {
    // String token = Auth.token;
    Dio _dio = Dio();
    _dio.options.baseUrl = Api.baseUrl;
    _dio.interceptors.add(CookieManager(await MyCookie.cookieJar));
    try {
      // // 获取用户名和密码
      String username = PreferenceUtils().getString(username_key);
      String password = PreferenceUtils().getString(password_key);

      Response response = await _dio.post(
        Api.encrypt_key + password,
      );
      Uri uri = Uri.parse(Api.baseUrl + Api.encrypt_key);
      List cookies =
          await (await MyCookie.cookieJar).loadForRequest(uri);
      // 清除所有cookie
      await (await MyCookie.cookieJar).deleteAll();
      await (await MyCookie.cookieJar).saveFromResponse(uri, cookies);

      // _dio.interceptors.add(this);
      if (response.statusCode == 200) {
        String token = '';

        // ignore: non_constant_identifier_names
        String password_key = response.data['data'];
        Map paras = {
          "flag": "1",
          "password": password_key,
          "username": username
        };
        Response tokenResponse =
            await _dio.post(Api.baseUrl + Api.login, data: paras);
        if (tokenResponse.statusCode == 200 && tokenResponse.data['success']) {
          token = tokenResponse.data['data']['access_token'];
          PreferenceUtils().saveString(Authorization_key, token);
          print('newToken: $token');
          return token;
        }
        return null;
      }
    } on DioError catch (e) {
      print(e.message);
      handler.next(e);
    }
    return null;
  }
}

你可能感兴趣的:(flutter 自动刷新token)