Search code examples
httpauthenticationflutteroauth-2.0refresh-token

Flutter http authenticator service to refresh oauth2 token


I am working on oauth2 authentication in a flutter app. I am thinking of refreshing the token when 401 authentication error happens in any of my API's. So how to add an authenticator service to all the http requests in flutter. In android we have okhttp authenticator to detect the authentication error during any API call and can refresh the token and proceed the previous API call. In flutter how to implement this? I dont think it is a good practice to handle 401 error in all the API's.


Solution

  • Use dio interceptor

    Below is a snippet from my interceptor

     dio.interceptors
            .add(InterceptorsWrapper(onRequest: (RequestOptions options) async {
    
    /* Write your request logic setting your Authorization header from prefs*/
    
          String token = await prefs.accessToken;
          if (token != null) {
            options.headers["Authorization"] = "Bearer " + token;
          return options; //continue
        }, onResponse: (Response response) async {
    // Write your response logic
    
          return response; // continue
        }, onError: (DioError dioError) async {
    
          // Refresh Token
          if (dioError.response?.statusCode == 401) {
            Response response;
            var data = <String, dynamic>{
              "grant_type": "refresh_token",
              "refresh_token": await prefs.refreshToken,
              'email': await prefs.userEmail
            };
            response = await dio
                .post("api/url/for/refresh/token", data: data);
            if (response.statusCode == 200) {
              var newRefreshToken = response.data["data"]["refresh_token"]; // get new refresh token from response
              var newAccessToken = response.data["data"]["access_token"]; // get new access token from response
              prefs.refreshToken = newRefreshToken;
              prefs.accessToken = newAccessToken; // to be used in the request section of the interceptor
              return dio.request(dioError.request.baseUrl + dioError.request.path,
                  options: dioError.request);
            }
          }
          return dioError;
        }));
        return dio;
      }
    }