J'essaie d'utiliser Interceptor avec Dio en flutter, je dois gérer l'expiration du jeton. voici mon 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;
}
problème est au lieu de répéter l'appel réseau avec le nouveau jeton, Dio renvoie l'objet d'erreur à la méthode d'appel, qui à son tour rend le mauvais widget, des pistes sur la façon de gérer l'actualisation du jeton avec dio?
Je l'ai résolu en utilisant des intercepteurs de la manière suivante: -
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;
}
Vous obtiendrez un code d'état de réponse 401 pour l'expiration du jeton. Afin de demander un nouveau jeton d'accès, vous devez utiliser la méthode post avec données de formulaire et les Dio options (type de contenu et en-têtes) requis. Ci-dessous, le code montre comment demander un nouveau jeton.
Une fois la demande réussie, si vous obtenez le code d'état de réponse 200, vous obtiendrez une nouvelle valeur de jeton d'accès ainsi qu'une valeur de jeton d'actualisation et les enregistrerez dans le stockage que vous préférez utiliser. Par exemple, Préférences partagées.
Une fois que vous avez enregistré un nouveau jeton d'accès, vous pouvez l'utiliser pour récupérer des données en utilisant la méthode get indiquée dans le même code ci-dessous.
onError(DioError error) async {
if (error.response?.statusCode == 401) {
Response response;
var authToken = base64
.encode(utf8.encode("username_value" + ":" + "password_value"));
FormData formData = new FormData.from(
{"grant_type": "refresh_token", "refresh_token": refresh_token_value});
response = await dio.post(
url,
data: formData,
options: new Options(
contentType: ContentType.parse("application/x-www-form-urlencoded"),
headers: {HttpHeaders.authorizationHeader: 'Basic $authToken'}),
);
if (response.statusCode == 200) {
response = await dio.get(
url,
options: new Options(headers: {
HttpHeaders.authorizationHeader: 'Bearer access_token_value'
}),
);
return response;
} else {
print(response.data);
return null;
}
}
return error;
}
Je n'ai pas encore terminé l'implémentation du client Http personnalisé, mais cela peut vous aider.