Files
swift_companion/docs/pedagogie/etape-02-oauth-intra.md
2026-09-29 15:07:05 +02:00

179 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Étape 2 — OAuth2 Intra + token unique
> **Prérequis :** étape 1 OK (`swiftyCompanion/swifty_companion/` créé, `flutter run` fonctionne).
## Objectif de l’étape
1. Obtenir un **access token** via **OAuth2 de l’Intra** (pas un token par requête API).
2. Stocker les secrets dans **`.env`** (racine `swiftyCompanion/` ou dossier `swifty_companion/` — un seul endroit, documenté dans le README).
3. Avoir un **service d’auth** réutilisable pour toutes les futures requêtes `api.intra.42.fr`.
Les **vues** (recherche login, profil) viennent aux étapes 3–4 ; ici on pose l’authentification API.
---
## 2.1 — Vérifier l’app
```bash
cd ~/projets/42School/swifty_companion/swiftyCompanion/swifty_companion
flutter pub get
flutter run -d <device>
```
L’écran compteur par défaut suffit pour valider l’étape 1.
---
## 2.2 — Créer l’application OAuth sur l’Intra
1. [profile.intra.42.fr/oauth/applications](https://profile.intra.42.fr/oauth/applications) → **New application**.
2. Renseigner :
- **Name** : ex. `swifty_companion_dev`
- **Website** : URL factice ou repo perso (souvent requis)
- **Redirect URI** : doit correspondre **exactement** à ce que l’app utilisera (voir 2.3)
3. Noter **UID** (= `CLIENT_ID`) et **SECRET** (= `CLIENT_SECRET`).
Copier `swiftyCompanion/.env.example` → `.env` (même niveau que le README rendu ou dans `swifty_companion/`) :
```env
CLIENT_ID=...
CLIENT_SECRET=...
REDIRECT_URI=...
```
---
## 2.3 — Choisir le `REDIRECT_URI` (mobile)
### Erreur Intra : « must be a valid URI »
Le formulaire **42 Intra** accepte en pratique surtout des URI **`http://` ou `https://`**.
Les schémas du type `com.example.swifty_companion://callback` sont souvent **refusés** (validateur strict + `_` dans le schéma).
**Type d’application Intra :** `42 pedagogic project` (normal pour Swifty Companion — pas de type « mobile »).
**URI de redirection** — format **http(s)://host:port/chemin** uniquement (pas de `com.example://…`).
Essayer **dans cet ordre** (une seule ligne dans le champ, sans guillemets ni espace) :
1. `http://localhost:8080/callback` ← le plus courant sur l’Intra 42
2. `http://localhost:3000/callback`
3. `http://127.0.0.1:8080/callback`
Exemple tiré de la [doc 42](https://api.intra.42.fr/apidoc/guides/web_application_flow) :
`http://localhost:1919/users/auth/ft/callback` (tu peux t’en inspirer, mais garde une URI simple type `/callback`).
Copier **exactement** la ligne acceptée dans `.env` et dans Flutter.
Avec `flutter_appauth`, Android/iOS interceptent cette URL de boucle locale après le login dans le navigateur — pas besoin d’un vrai serveur web.
| Approche | Redirect URI | Intra 42 |
|----------|--------------|----------|
| **Recommandé (Flutter + 42)** | `http://127.0.0.1:42800/callback` | ✅ en général accepté |
| Schéma custom | `com.example.swifty_companion://callback` | ❌ souvent refusé |
| Site web classique | `https://ton-domaine.com/callback` | ✅ si tu as un backend |
Le même URI doit être : formulaire Intra, `.env`, et paramètre `redirect_uri` dans l’app.
**Android** : `applicationId` = `com.example.swifty_companion` (`android/app/build.gradle.kts`) — indépendant du `REDIRECT_URI` loopback.
Endpoints 42 (référence) :
| Étape | URL |
|-------|-----|
| Autorisation | `GET https://api.intra.42.fr/oauth/authorize` |
| Token | `POST https://api.intra.42.fr/oauth/token` |
| API | `GET https://api.intra.42.fr/v2/...` avec header `Authorization: Bearer <token>` |
Paramètres authorize usuels : `client_id`, `redirect_uri`, `response_type=code`, `scope=public projects` (voir [intra-oauth-formulaire.md](intra-oauth-formulaire.md)).
---
## 2.4 — Dépendances Flutter suggérées
Dans `swifty_companion/` :
```bash
flutter pub add flutter_dotenv http
# selon le flux choisi, par ex. :
# flutter pub add flutter_appauth
```
| Package | Rôle |
|---------|------|
| `flutter_dotenv` | Charger `.env` au démarrage |
| `http` | Échange code → token + appels API |
| `flutter_appauth` | Flux OAuth2 + redirect natif (optionnel mais pratique) |
---
## 2.5 — Architecture minimale (fichiers à créer)
```
lib/
├── main.dart # dotenv.load + MaterialApp
├── config/
│ └── env.dart # lecture CLIENT_ID, etc.
└── services/
└── intra_auth_service.dart # token en mémoire (singleton)
```
Règles sujet :
- **Un seul token** : le service le garde après le login OAuth ; les futures requêtes réutilisent `getAccessToken()`.
- **Ne pas** appeler `/oauth/token` avant chaque `GET /v2/users/...`.
Pseudo-contrat du service :
```dart
class IntraAuthService {
String? _accessToken;
String? get accessToken => _accessToken;
bool get isAuthenticated => _accessToken != null;
Future<void> signIn(); // ouvre le flux OAuth, stocke le token
Future<String> getValidToken(); // retourne le token (bonus : refresh plus tard)
}
```
Test manuel étape 2 : bouton « Se connecter à l’Intra » → navigateur / WebView → retour app → afficher temporairement « Connecté » ou le login `/v2/me`.
---
## 2.6 — `.env` et assets
Si `flutter_dotenv` charge depuis la racine du package Flutter :
1. Placer `.env` dans `swifty_companion/` (ignoré par git).
2. Déclarer dans `pubspec.yaml` :
```yaml
flutter:
assets:
- .env
```
> En production soutenance : les correcteurs créent **leur** `.env` avec **leur** app OAuth ; ne jamais committer le fichier.
---
## 2.7 — Critère « terminé » pour l’étape 2
| Check | OK si |
|-------|--------|
| OAuth Intra | Connexion obtient un access token |
| Token unique | Plusieurs appels API utilisent le **même** token sans re-login |
| Secrets | Uniquement dans `.env`, pas dans le code en dur |
| Doc | README rendu rappelle où mettre `.env` et comment lancer l’app |
---
## Ensuite — étape 3
→ [etape-03-vue-recherche.md](etape-03-vue-recherche.md) (à rédiger quand l’étape 2 est validée) : **vue 1** — champ login, appel API, erreurs 404 / réseau.
Documentation API utile :
- [apidoc](https://api.intra.42.fr/apidoc)
- User : `GET /v2/users/:id` ou recherche par login (voir doc)