Maison >développement back-end >Tutoriel Python >Comment rediriger avec des cookies et des en-têtes entre domaines en HTTP ?
Redirection d'un domaine à un autre avec des en-têtes personnalisés ou les cookies définis dans la réponse ne sont pas possibles en raison des limitations du protocole HTTP. Une redirection consiste essentiellement en un en-tête (Location) associé à la réponse, et elle ne permet pas d'ajouter d'en-tête à l'emplacement cible.
La configuration de cookies pour un domaine différent n'est pas non plus autorisée car cela le ferait posent un risque de sécurité important. Les navigateurs stockent les cookies envoyés par le serveur avec une réponse à l'aide de l'en-tête Set-Cookie, puis les renvoient ensuite au serveur pour les requêtes adressées au même serveur dans le même domaine. Les cookies ne sont pas envoyés vers un domaine différent.
Une approche consiste à demander au domaine source de rediriger l'utilisateur vers le domaine cible avec un jeton d'accès passé en paramètre de requête. Le domaine cible peut ensuite lire le jeton et définir son propre cookie, que le navigateur stockera et enverra pour les demandes ultérieures.
Domaine source (appA.py)
<code class="python">from fastapi import FastAPI, Response from fastapi.responses import RedirectResponse, HTMLResponse app = FastAPI() @app.get('/', response_class=HTMLResponse) def home(): return ''' <!DOCTYPE html> <html> <body> <h2>Click the "submit" button to be redirected to domain B</h2> <form method="POST" action="/submit"> <input type="submit" value="Submit"> </form> </body> </html> ''' @app.post('/submit') def submit(): token = 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3' redirect_url = f'http://example.test:8001/submit?token={token}' response = RedirectResponse(redirect_url) response.set_cookie(key='access-token', value=token, httponly=True) return response</code>
Domaine cible (appB.py)
<code class="python">from fastapi import FastAPI, Request, status from fastapi.responses import RedirectResponse, HTMLResponse app = FastAPI() @app.get('/', response_class=HTMLResponse) def home(): token = request.cookies.get('access-token') print(token) return 'You have been successfully redirected to domain B!' \ f' Your access token ends with: {token[-4:]}' @app.post('/submit') def submit(request: Request, token: str): redirect_url = request.url_for('home') response = RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER) response.set_cookie(key='access-token', value=token, httponly=True) return response</code>
Une autre approche consiste à utiliser Window. postMessage() pour la communication entre origines. Le domaine source envoie le jeton au domaine cible, qui le stocke dans localStorage et définit un cookie. Les inconvénients incluent la compatibilité du navigateur et le stockage des données sensibles dans localStorage.
Une solution plus robuste est utilisée par StackExchange pour la connexion automatique entre ses différents sites. Cela implique l'envoi d'un jeton d'authentification via l'attribut src d'une image, qui déclenche une réponse du serveur et définit des cookies sur le site cible.
Cela nécessite l'acceptation par le navigateur des cookies tiers et la configuration CORS sur le serveur cible. Il envoie également le jeton dans la chaîne de requête, ce qui présente des risques de sécurité potentiels.
Domaine source (appA.py)
<code class="python">from fastapi import FastAPI, Response from fastapi.responses import HTMLResponse app = FastAPI() @app.get('/', response_class=HTMLResponse) def home(): return ''' <!DOCTYPE html> <html> <body> <h2>Click the "submit" button to be redirected to domain B</h2> <input type="button" value="Submit" onclick="submit()"> <script> function submit() { fetch('/submit', { method: 'POST', }) .then(res => { authHeader = res.headers.get('Authorization'); if (authHeader.startsWith("Bearer ")) token = authHeader.substring(7, authHeader.length); return res.text(); }) .then(data => { var url = 'http://example.test:8001/submit?token=' + encodeURIComponent(token); var img = document.createElement('img'); img.style = 'display:none'; img.crossOrigin = 'use-credentials'; img.onerror = function(){ window.location.href = 'http://example.test:8001/'; } img.src = url; }) .catch(error => { console.error(error); }); } </script> </body> </html> ''' @app.post('/submit') def submit(): token = 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3' headers = {'Authorization': f'Bearer {token}'} response = Response('success', headers=headers) response.set_cookie(key='access-token', value=token, httponly=True) return response</code>
Domaine cible (appB .py)
<code class="python">from fastapi import FastAPI, Request, Response from fastapi.responses import RedirectResponse from fastapi.middleware.cors import CORSMiddleware app = FastAPI() origins = ['http://localhost:8000', 'http://127.0.0.1:8000', 'https://localhost:8000', 'https://127.0.0.1:8000'] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get('/') def home(request: Request): token = request.cookies.get('access-token') print(token) return 'You have been successfully redirected to domain B!' \ f' Your access token ends with: {token[-4:]}' @app.get('/submit') def submit(request: Request, token: str): response = Response('success') response.set_cookie(key='access-token', value=token, samesite='none', secure=True, httponly=True) return response</code>
Lors du transfert de jetons ou de la configuration de cookies entre domaines, il est crucial de prendre en compte les implications en matière de sécurité. Évitez d'envoyer des données sensibles dans la chaîne de requête car elles peuvent être interceptées ou compromises. Utilisez des connexions HTTPS pour un transfert de données sécurisé. Définissez l'indicateur SameSite sur « Aucun » avec l'indicateur Sécurisé pour la protection de l'accès entre sites.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!