Rumah >pembangunan bahagian belakang >Tutorial Python >Bagaimana untuk mengubah hala dengan Kuki dan Pengepala Antara Domain dalam HTTP?
Ubah hala dari satu domain ke domain lain dengan pengepala tersuai atau kuki yang ditetapkan dalam respons tidak mungkin disebabkan oleh pengehadan protokol HTTP. Ubah hala pada asasnya terdiri daripada pengepala (Lokasi) yang dikaitkan dengan respons dan ia tidak membenarkan sebarang pengepala ditambahkan pada lokasi sasaran.
Menetapkan kuki untuk domain lain juga tidak dibenarkan kerana ia akan menimbulkan risiko keselamatan yang ketara. Penyemak imbas menyimpan kuki yang dihantar oleh pelayan dengan respons menggunakan pengepala Set-Cookie, dan kemudian menghantarnya kembali ke pelayan untuk permintaan yang dibuat ke pelayan yang sama dalam domain yang sama. Kuki tidak dihantar ke domain lain.
Salah satu pendekatan ialah meminta domain sumber mengubah hala pengguna ke domain sasaran dengan token akses diluluskan sebagai parameter pertanyaan. Domain sasaran kemudiannya boleh membaca token dan menetapkan kukinya sendiri, yang akan disimpan dan dihantar oleh penyemak imbas untuk permintaan seterusnya.
Domain Sumber (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>
Domain Sasaran (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>
Pendekatan lain melibatkan penggunaan Window. postMessage() untuk komunikasi silang asal. Domain sumber menghantar token ke domain sasaran, yang menyimpannya dalam localStorage dan menetapkan kuki. Kelemahan termasuk keserasian penyemak imbas dan penyimpanan data sensitif dalam localStorage.
Penyelesaian yang lebih mantap digunakan oleh StackExchange untuk log masuk automatik antara tapak yang berbeza. Ia melibatkan penghantaran token pengesahan melalui atribut src imej, yang mencetuskan respons pelayan dan menetapkan kuki pada tapak sasaran.
Ini memerlukan penerimaan penyemak imbas kuki pihak ketiga dan konfigurasi CORS pada pelayan sasaran. Ia juga menghantar token dalam rentetan pertanyaan, menimbulkan potensi risiko keselamatan.
Domain Sumber (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>
Domain Sasaran (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>
Apabila memindahkan token atau menetapkan kuki antara domain, adalah penting untuk mempertimbangkan implikasi keselamatan. Elakkan daripada menghantar data sensitif dalam rentetan pertanyaan kerana ia boleh dipintas atau dikompromi. Gunakan sambungan HTTPS untuk pemindahan data selamat. Tetapkan bendera SameSite kepada 'Tiada' dengan bendera Selamat untuk perlindungan akses merentas tapak.
Atas ialah kandungan terperinci Bagaimana untuk mengubah hala dengan Kuki dan Pengepala Antara Domain dalam HTTP?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!