美文网首页
flutter 自动刷新token

flutter 自动刷新token

作者: smallLabel | 来源:发表于2021-07-14 00:14 被阅读0次

    创建一个拦截器
    重写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<String?> 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<Cookie> 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<String, dynamic> 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

          本文链接:https://www.haomeiwen.com/subject/wbuepltx.html