ホームページ  >  記事  >  バックエンド開発  >  ドメイン間でリダイレクトして Cookie またはヘッダーを設定するにはどうすればよいですか?

ドメイン間でリダイレクトして Cookie またはヘッダーを設定するにはどうすればよいですか?

DDD
DDDオリジナル
2024-10-31 05:30:01309ブラウズ

How to Redirect Between Domains and Set Cookies or Headers?

あるドメインから別のドメインにリダイレクトし、他のドメインに Cookie またはヘッダーを設定するにはどうすればよいですか?

ここで説明されているように、カスタム ヘッダーが設定された別のドメインにリダイレクトすることはできません。どのような言語やフレームワークを使用しているかは関係ありません。 HTTP プロトコルのリダイレクトは基本的に応答に関連付けられたヘッダー (つまり、場所) であり、ターゲットの場所へのヘッダーを追加することはできません。例に Authorization ヘッダーを追加する場合、基本的にそのヘッダーは、リダイレクト自体ではなく、ブラウザーにリダイレクトするように指示する応答に設定されます。言い換えると、そのヘッダーをクライアントに送り返します

HTTP Cookie に関しては、ブラウザはサーバーから応答とともに送信された Cookie を (Set-Cookie を使用して) 保存します。ヘッダー))、その後、Cookie HTTP ヘッダー内の 同じサーバー に対して行われたリクエストとともに Cookie を送信します。ドキュメントによると:

Set-Cookie HTTP 応答ヘッダーは、
サーバーからユーザー エージェントに Cookie を送信するために使用され、ユーザー エージェントがそれをサーバーに送り返すことができます
後で。複数の Cookie を送信するには、複数の Set-Cookie
ヘッダーを同じ応答で送信する必要があります。

したがって、これが 1 つのアプリからのリダイレクト (サブドメイン、例: abc.example.test) の場合、 ) 両方とも同じ (親) ドメインを持つ別の (サブドメイン、例: xyz.example.test) に送信すると (Cookie の作成時にドメイン フラグが example.test に設定されている)、Cookie はそれらの間で正常に共有されます。 2 つのアプリ (ドメインが指定されているかのように、サブドメインが常に含まれます)。ブラウザは、使用されているプロトコル (HTTP/HTTPS) またはポートに関係なく、サブドメインを含む指定されたドメインで Cookie を利用できるようにします。ドメイン フラグとパス フラグを使用して Cookie の利用を制限したり、secure フラグや httpOnly フラグを使用して Cookie へのアクセスを制限したりできます (こちらとこちら、および Starlette のドキュメントを参照してください)。 httpOnly フラグが設定されていない場合、潜在的な攻撃者は JavaScript (JS) を通じて情報を読み取り、変更することができますが、httpOnly 属性を持つ Cookie はサーバーにのみ送信され、クライアント側の JS にはアクセスできません。

ただし、別のドメインに Cookie を設定することはできません。これが許可されると、セキュリティ上、重大な欠陥が生じることになります。したがって、"Cookie を設定してあるアプリケーション (ドメイン) から別のアプリケーション (ドメイン) にユーザーをリダイレクトしようとしているため、...*""、Cookie は送信されるだけであるため、機能しません。 同じドメインに対してリクエストが行われた場合。

解決策 1

ここで説明する解決策は、URL にクエリ パラメータとして渡されたアクセス トークンを使用して、ドメイン (アプリ) A がユーザーをドメイン (アプリ) B にリダイレクトすることです。次に、ドメイン B はトークンを読み取り、独自の Cookie を設定します。これにより、ブラウザはその Cookie を保存し、その後のドメイン B へのリクエストごとにその Cookie を送信します。

安全な (HTTPS) 通信の使用を検討する必要があることに注意してください。 、トークンが暗号化されて転送されるようにするだけでなく、Cookie の作成時にセキュア フラグを設定します。また、機密データはクエリ文字列で渡されるべきではないため、クエリ文字列にトークンを含めることは重大なセキュリティ リスクを引き起こすことにも注意してください。これは、URL の一部であるクエリ文字列がブラウザのアドレス バーに表示されるためです。これにより、ユーザーはトークンが含まれる URL を表示してブックマークできるようになります (つまり、トークンはディスクに保存されます)。また、URL は閲覧履歴に残ります。つまり、いずれにしてもディスクに書き込まれ、[履歴] タブに表示されます (ブラウザの履歴を表示するには、Ctrl H を押します)。上記の両方により、攻撃者 (およびコンピュータ/モバイル デバイスを共有する人々) がそのような機密データを盗むことが可能になります。さらに、多くのブラウザ プラグイン/拡張機能はユーザーの閲覧アクティビティを追跡します。悪意のある Web サイトを検出して事前に警告するために、アクセスしたすべての URL が分析のためにサーバーに送信されます。したがって、以下のアプローチを使用する前に、上記のすべてを考慮する必要があります (この主題に関する関連記事については、ここ、ここ、およびここを参照してください)。

アドレス バーに URL が表示されないようにするには、以下のアプローチを使用します。ドメイン B 内でもリダイレクトを使用します。ドメイン B がクエリ パラメーターとしてトークンを含む /submit ルートへのリクエストを受信すると、ドメイン B はトークンが含まれていない裸の URL (つまり、そのホームページ) へのリダイレクトで応答します。このリダイレクトにより、トークンが含まれる URL は閲覧履歴に残りません。これにより、前述した特定の攻撃に対するある程度の保護が提供されますが、ブラウザ拡張機能などがトークンを含む URL をキャプチャできないという意味ではありません。

これをテストしている場合ローカルホストでは、アプリケーション B に別のドメイン名を与える必要があります。そうしないと、前述したように、同じドメインを持つアプリケーション間で Cookie が共有されるため、ドメイン A に設定された Cookie を受け取ることになり、このアプローチが機能しているかどうかがまったくわかりません。これを行うには、/etc/hosts ファイル (Windows では C:WindowsSystem32driversetc にあります) を編集し、ホスト名を 127.0.0.1 に割り当てる必要があります。例:

127.0.0.1 example.test

スキームやポートをドメインに追加しないでください。また、.com、.net などの一般的な拡張子も使用しないでください。そうしないと、競合する可能性があります。インターネット上の他の Web サイトにアクセスする場合。

以下のドメイン A にアクセスしたら、送信ボタンをクリックして /submit ルートへの POST リクエストを実行し、リダイレクトを開始する必要があります。 POST リクエストの唯一の理由は、例で POST リクエストを使用しており、フォームデータを投稿する必要があると想定しているためです。それ以外の場合は、GET リクエストを使用することもできます。アプリ B では、POST ルート (/submit) から GET ルート (/) への RedirectResponse を実行すると、ここ、ここ、およびここで説明されているように、応答ステータス コードが status.HTTP_303_SEE_OTHER に変わります。アプリ A はポート 8000 でリッスンし、アプリ B はポート 8001 でリッスンします。

以下の両方のアプリを実行し、http://127.0.0.1:8000/ でドメイン A にアクセスします。

appA.py

127.0.0.1 example.test

appB.py

<code class="python">from fastapi import FastAPI, FastAPI
from fastapi.responses import RedirectResponse, HTMLResponse
import uvicorn

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)  # set cookie for domain A too
    return response
 
if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)</code>

解決策 2

もう 1 つの解決策は、Window オブジェクト間のクロスオリジン通信を可能にする Window.postMessage() を使用することです。たとえば、ページとそれが生成したポップアップの間、またはページとその中に埋め込まれた iframe の間などです。イベント リスナーを追加し、ウィンドウ間で通信する方法の例は、ここにあります。実行する手順は次のとおりです:

ステップ 1: ドメイン A に非表示の iframe をドメイン B に追加します。例:

<code class="python">from fastapi import FastAPI, Request, status
from fastapi.responses import RedirectResponse
import uvicorn

app = FastAPI()

@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.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
 
if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8001)</code>

ステップ 2 :

から認可トークンを取得するとすぐに

以上がドメイン間でリダイレクトして Cookie またはヘッダーを設定するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。