在 Dio 中使用 Interceptor for Flutter 刷新 Token [英] Using Interceptor in Dio for Flutter to Refresh Token

查看:241
本文介绍了在 Dio 中使用 Interceptor for Flutter 刷新 Token的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在颤动中使用 Interceptor 和 Dio,我必须处理令牌过期.以下是我的代码

I am trying to use Interceptor with Dio in flutter, I have to handle Token expire. following is my code

Future<Dio> getApiClient() async {
    token = await storage.read(key: USER_TOKEN);
    _dio.interceptors.clear();
    _dio.interceptors
        .add(InterceptorsWrapper(onRequest: (RequestOptions options) {
      // Do something before request is sent
      options.headers["Authorization"] = "Bearer " + token;
      return options;
    },onResponse:(Response response) {
        // Do something with response data
        return response; // continue
    }, onError: (DioError error) async {
      // Do something with response error
      if (error.response?.statusCode == 403) {
        // update token and repeat
        // Lock to block the incoming request until the token updated

        _dio.interceptors.requestLock.lock();
        _dio.interceptors.responseLock.lock();
        RequestOptions options = error.response.request;
        FirebaseUser user = await FirebaseAuth.instance.currentUser();
        token = await user.getIdToken(refresh: true);
        await writeAuthKey(token);
        options.headers["Authorization"] = "Bearer " + token;

        _dio.interceptors.requestLock.unlock();
        _dio.interceptors.responseLock.unlock();
        _dio.request(options.path, options: options);
      } else {
        return error;
      }
    }));
    _dio.options.baseUrl = baseUrl;
    return _dio;
  }

问题是,Dio 没有使用新令牌重复网络调用,而是将错误对象返回给调用方法,这反过来又渲染了错误的小部件,有关如何使用 dio 处理令牌刷新的任何线索?

problem is instead of repeating the network call with the new token, Dio is returning the error object to the calling method, which in turn is rendering the wrong widget, any leads on how to handle token refresh with dio?

推荐答案

我通过以下方式使用拦截器解决了它:-

I solved it using interceptors in following way :-

  Future<Dio> getApiClient() async {
    token = await storage.read(key: USER_TOKEN);
    _dio.interceptors.clear();
    _dio.interceptors
        .add(InterceptorsWrapper(onRequest: (RequestOptions options) {
      // Do something before request is sent
      options.headers["Authorization"] = "Bearer " + token;
      return options;
    },onResponse:(Response response) {
        // Do something with response data
        return response; // continue
    }, onError: (DioError error) async {
      // Do something with response error
      if (error.response?.statusCode == 403) {
        _dio.interceptors.requestLock.lock();
        _dio.interceptors.responseLock.lock();
        RequestOptions options = error.response.request;
        FirebaseUser user = await FirebaseAuth.instance.currentUser();
        token = await user.getIdToken(refresh: true);
        await writeAuthKey(token);
        options.headers["Authorization"] = "Bearer " + token;

        _dio.interceptors.requestLock.unlock();
        _dio.interceptors.responseLock.unlock();
        return _dio.request(options.path,options: options);
      } else {
        return error;
      }
    }));
    _dio.options.baseUrl = baseUrl;
    return _dio;
  }

Dio 4.0.0 支持

Dio 4.0.0 Support

    dio.interceptors.add(
          InterceptorsWrapper(
            onRequest: (request, handler) {
              if (token != null && token != '')
                request.headers['Authorization'] = 'Bearer $token';
              return handler.next(request);
            },
            onError: (e, handler) async {
              if (e.response?.statusCode == 401) {
                try {
                  await dio
                      .post(
                          "https://refresh.api",
                          data: jsonEncode(
                              {"refresh_token": refreshtoken}))
                      .then((value) async {
                    if (value?.statusCode == 201) {
                      //get new tokens ...
                      print("access token" + token);
                      print("refresh token" + refreshtoken);
                      //set bearer
                      e.requestOptions.headers["Authorization"] =
                          "Bearer " + token;
                      //create request with new access token
                      final opts = new Options(
                          method: e.requestOptions.method,
                          headers: e.requestOptions.headers);
                      final cloneReq = await dio.request(e.requestOptions.path,
                          options: opts,
                          data: e.requestOptions.data,
                          queryParameters: e.requestOptions.queryParameters);
    
                      return handler.resolve(cloneReq);
                    }
                    return e;
                  });
                  return dio;
                } catch (e, st) {
                  
                }
              }
           },
        ),
    );

这篇关于在 Dio 中使用 Interceptor for Flutter 刷新 Token的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆