Google Photos exige le header Authorization, OneDrive l'interdit
Télécharger une photo utilisateur, deux clouds, deux comportements opposés sur le même header HTTP. Le genre de détail qui coûte une journée de debug.
Même besoin : télécharger une photo de l'utilisateur. Chez Google Photos, la requête échoue sans le header Authorization. Chez OneDrive, elle échoue avec.

Une journée de debug pour comprendre ça, alors que tout est documenté. Mais documenté chacun de son côté, et personne ne fait le rapprochement. Le contraste mérite un post à lui seul.
Google Photos : l'URL ne suffit jamais
La Picker API de Google Photos renvoie des baseUrl pour chaque média sélectionné. Ces URLs ont l'air auto-suffisantes, elles ne le sont pas : le téléchargement du binaire exige le token OAuth dans le header, comme n'importe quel appel API. Et elles expirent en une heure environ : pas de mise en cache des URLs, seulement des fichiers.
GET {baseUrl}=d
Authorization: Bearer ya29.a0...
Sans le header : erreur d'authentification, même avec une baseUrl fraîche. L'URL identifie la ressource, le header prouve le droit d'accès. Deux choses séparées.
OneDrive : l'URL est le droit d'accès
Microsoft Graph renvoie pour chaque fichier une propriété @microsoft.graph.downloadUrl. Celle-ci est pré-signée : la preuve d'accès est encodée dans l'URL elle-même, comme une URL signée S3 ou GCS. Courte durée de vie, aucune authentification supplémentaire attendue.
Et c'est là que ça casse : si votre client HTTP ajoute machinalement le header Authorization (un intercepteur Dio global, par exemple), la requête échoue. Le endpoint de téléchargement pré-signé rejette les requêtes qui portent une authentification surnuméraire.
// L'intercepteur global qui vous veut du bien...
dio.interceptors.add(AuthInterceptor()); // ajoute Authorization partout
// ...casse spécifiquement les downloadUrl OneDrive.
// Fix : un client nu pour les URLs pré-signées.
final bareDio = Dio();
await bareDio.download(microsoftDownloadUrl, path);
La leçon générale
Le réflexe « j'ajoute le token partout, au pire il est ignoré » est faux. Un header d'authentification n'est pas neutre : sur une URL pré-signée, il entre en conflit avec la signature.
La bonne question devant chaque URL de téléchargement : qui porte la preuve d'accès ?
- La preuve est dans le header → URL nue, token obligatoire (Google Photos).
- La preuve est dans l'URL → header interdit ou ignoré, et votre intercepteur global est un risque (OneDrive, S3, GCS signées).
Concrètement, dans une app qui agrège plusieurs clouds : deux clients HTTP. Un authentifié pour les appels API, un nu pour les URLs pré-signées. L'intercepteur global unique est le bug qui attend.
À retenir
- Google Photos :
baseUrl+ headerAuthorizationobligatoire pour le binaire. - OneDrive :
@microsoft.graph.downloadUrlpré-signée, headerAuthorizationfatal. - Classez chaque URL de téléchargement : preuve dans le header ou preuve dans l'URL. Le client HTTP en découle.
Votre intercepteur d'auth global a-t-il déjà cassé une URL signée chez vous ?