5

複数のアプリケーションにフィードするサーバーがあります。

私はこれらのアプリケーションの 2 つ以上に登録されたユーザーであり、それぞれにアクセスするときに 1 つの異なるログイン情報を使用していると想像してください。

今、そのユーザーとして、同じブラウザーを使用して異なるタブでそれらのアプリケーションにアクセスしています...初めてログに記録すると(最初のアプリケーションの場合)、すべてが意図したとおりに進みますが、2番目のアプリケーションに(2番目のユーザーとして)アクセスすると、そのリクエストは同じrequest.sessionオブジェクトにアクセスします。(認証フレームワークから)ログインを呼び出すと、現在のユーザーが実際のユーザーと比較されrequest.sessionrequest.session[SESSION_KEY] != user.id)、request.session.flush()呼び出されます。

これはrequest.session、最初のアプリケーションにアクセスしたユーザーのすべてのコンテンツを失い、その同じユーザーがその時点からrequest.session2 番目のユーザーとして「マーク」されることを意味します。request.session

この状況で私が欲しかったのはrequest.session、元のユーザーをそのままにして、2 番目のユーザー用に新しいユーザーを作成できる関数/メソッドを持つことでした。

最初の回答の後に編集: まず、回答ありがとうございます。あまりにも的を射た回答を避けるために、あまり詳細にならないようにしていましたが、今ではそうすべきだと思います。

わかりました、以前に「それ」アプリケーションと呼んだことがありますが、実際には、私のプロジェクトは同じ最終的な「製品」(たとえばゲーム) を提供するためにリクエストを処理します。(私は自分のプロジェクト内にいくつかの django アプリケーションを持っています。適用されるビジネス上の考慮事項に応じて、特定の方向性とバックエンドがそれぞれに適用されます。)

異なるエントリ ポイント URL があり、正しいビジネス バックエンドを使用してリクエストを処理し、ゲームを取得することを伝えれば、より詳細になります。

メイン URL は同じ (名前空間) で、プロジェクトには設定ファイルが 1 つしかありません。

ここに画像の説明を入力

4

2 に答える 2

2

「ユースケース」を変更する準備ができているかどうかに応じて、質問に対する回答がいくつかある場合があります。

a)ユース ケースを変更することはできません。1 つの Django セッションが複数のブラウザー ウィンドウ インスタンスまたはタブであるブラウザー セッションにバインドされているため、それは不可能です。

b)ユース ケースを変更できます: ユーザーは、コードを変更することなく、複数のブラウザー (またはプロファイル (または chrome/chromium のプライベート ブラウジング モード)) を使用してこれを実現できます。

c)ウェブサイトに「ユーザー」スイッチ機能を実装して、ユーザーが異なるウィンドウの同じセッションで複数のアクティブなプロファイルを持つことができるようにすることができます。目的は github 組織スイッチ機能または facebook ページ/組織スイッチに似ていますが、 github や facebook の場合とは異なり、複数のタブで複数のユーザーのプロファイルを持つことができます。

c)を達成するには、「SubProfile」モデル インスタンスを「User」モデルにアタッチし、クエリ文字列パラメーターに基づいて受信リクエストごとに適切な SubProfile をアクティブ化し、リクエスト間でサブプロファイル情報を保持する必要があります。

1)Subprofileへの外部キーを持つモデルのようなものを既に持っていると思いますdjango.contrib.auth.models.User。ユーザーがサブプロファイルを変更できるようにするビューもあるかもしれません。subprofile-switch を機能させるには、サブプロファイルを使用している現在のタブ セッションで情報を永続化する必要があります。そのためには、クエリ文字列にパラメーターを追加する必要があります。これは、ユーザーではなくタブをバインドする唯一の場所であるためです。 -セッション。たとえば、「サブプロファイル = 123」。サブプロファイルをフォームなどで適切に検証する必要があります。ビューは次のようになります。

def select_subprofile(request):
   if request.method == 'POST':
      form = SubProfileSelectForm(request)
      if form.is_valid():   
          subprofile = form.cleaned_data['subprofile']
          url = '%s?subprofile' % (reverse('homepage'), subprofile) 
          return redirect(url)  # the redirect is something like '/homepage?subprofile=123'
   else:
      form = SubProfileSelectForm()
   return render(request, 'myapp/subprofile_select.html', {'form':form})

このビューは、各ゲームの最初のページにすることができます。

2)その後、現在のタブのユーザーのサブプロファイルを取得する必要があります。この件については、ミドルウェアでクエリ文字列を使用します( SO のハウツーと、それが何であるかわからない場合はDjango にバンドルされているミドルウェアの例SubProfileを探します) を使用して、現在のインスタンスをにアタッチできますrequest.user。ミドルウェアは、着信要求ごとに、クエリ文字列で見つかった現在のサブプロファイル情報に対応する SubProfile インスタンスを現在のユーザー オブジェクトにアタッチします。ミドルウェアは次のようになります。

class SubProfileMiddleware(object):

    def process_request(self, request):
        subprofile = request.GET.get('subprofile', None)
        if subprofile:
            # it's important to check for user here or malicious users will be
            # able to use Subprofiles of other users
            subprofile = Subprofile.objects.filter(user=request.user, id=subprofile)
            # This can also be written 
            # subprofile = request.user.subprofile_set.filter(id=subprofile)
            if not subprofile:
                # this is a malicious user
                raise Http403
            else:
                request.user.subprofile = subprofile
        else:
             # set default subprofile
             request.user.subprofile = self.user.default_subprofile

このようにして、アプリのすべてのビューで の属性のSubProfileインスタンスにアクセスできます。有効なクエリ文字列がある場合、ユーザーはこれらのサブプロファイルをアクティブにします。そうでない場合は、デフォルトのサブプロファイルです。subprofilerequest.usersubprofile=123

アプリケーションが、各インスタンスに壁があり、ユーザーがサブプロファイルを使用してメッセージを投稿できるモデルを持つアプリケーションでOrganizationあるとします。壁にメッセージを投稿する関数には次の署名がありpost_on_organization_wall(subprofile, message, organization)、この関数を使用するビューは次のようになります。

def organization_wall_post(request, organization):
    organization = Organization.objects.get_object_or_404(organization)
    if request.method == 'POST':
        form = MessageForm(request.POST)
        if form.is_valid():
             post_on_organization_wall(request.user.subprofile, message, organisation)
    else:
        form = MessageForm()
    return render(request, 'organisation/wall_post.html', {'form': form})

3)次に、リクエスト間でサブプロファイル情報を保持する必要があります。これを行う最も簡単な方法は、everycall を{% url %}独自のurlテンプレート タグに置き換えて、サブプロファイル キーのリクエスト クエリ文字列の存在を確認し、それをリクエストされた URL に追加することです。Django の url テンプレート タグ のコードを再利用できます。

于 2012-09-24T19:50:44.277 に答える
0

私があなたの問題を正しく理解している場合、問題は、ユーザーが異なっていても、アプリケーション間でセッションを共有していることです。これを解決するには、settings.pyでSESSION_COOKIE_DOMAIN、SESSION_COOKIE_PATH、またはSESSION_COOKIE_NAMEのいずれかを設定して、アプリケーションが他のセッションを妨害しないようにします。

于 2012-09-24T14:53:06.267 に答える