14

django-rest-auth のドキュメントでは、Facebook の統合について説明していますが、これには興味がありません。私の懸念は、Google 経由でソーシャル ログインを提供することです。私はこれをかなり長い間試してきましたが、他の誰かがこれをどのように行ったかについてのドキュメントを持っているかどうか疑問に思っています...大まかなスケッチでも役に立ちます. これまでのところ、この検索の結果は見つかりませんでした。私はほとんどそこにいますが、Django Rest Framework (DRF) ブラウズ可能な API で動作させることができません。

ここに私がこれまでに持っているものがあります: django-rest-auth github ページで提供されているデモ プロジェクトから始めて、ソーシャル ログイン テンプレートの HTML ページを変更して、「コード」と「access_token」の両方ではなく、「コード」入力のみを要求するようにしました。 . 有効なコード (Google の認証エンドポイントへの別のリクエストによって取得) を提供すると、これは正常に機能します。ブラウズ可能な API は、応答に「キー」(ユーザー用のアプリケーションの API トークン) を含む通常の Web ページをレンダリングします。django管理者を確認すると、すべてが機能しました-ユーザーがログインしている、電子メールが認証されているなど。これまでのところ良好です。

問題は、「コード」を提供する開始点と、最初にそのコードをグーグルから取得する方法です。以前に allauth パッケージを (成功して) 使用したときは、リンクをクリックするだけで、OAuth2 フロー全体を「見えないように」実行できました (つまり、コードを要求し、そのコードを使用してアクセス トークンを取得し、アクセス トークンを使用してユーザーの Google アカウント情報を取得します)。

そのシームレスなフローを再作成する (つまり、コードから始めない) ために、OAuth2 フローを中断し、Google から返されたコードを「インターセプト」して、そのコードを rest-auth ソーシャル ログイン API に POST できると考えました。allauth.socialaccount.providers.oauth2.views.OAuth2CallbackViewそのために、dispatch メソッドをオーバーライドし てカスタムを作成しました。

class CustomOAuth2CallbackView(OAuth2CallbackView):
    def dispatch(self, request):
        # gets the code correctly:
        code = request.GET['code']

        # rp is of type requests.methods.Response
        rp = requests.post(<REST-AUTH API ENDPOINT>, data = {'code':code})
        return rp

通常、このメソッドは、最初に Google の認証エンドポイントに提供したコールバック URI に Google が GET リクエストを送信したときに呼び出されます。このオーバーライドにより、そのコールバックで Google から返されたコードを正常に解析できます。POST リクエストは機能し、resp._content フィールドにユーザーのキーが含まれています。ただし、最終的には、DRF browsable API で意図したビューを生成できません。

コールスタックを調べてみると、rest_framework.views.APIView.dispatchが type のオブジェクトを返すことがわかりましたrest_framework.response.Response。ただし、requests.post上記のメソッドが完了すると、 type のインスタンスが返されますrequests.models.Response。その結果、適切な属性がなく、django ミドルウェアで失敗します。たとえば、acceptable_renderer属性も「get」メソッドもありません (これは で使用されdjango.middleware.clickjacking.pyます)。requests.models.Responseおそらく、これらの要件を( ) インスタンスに追加することもできrpますが、このハックはさらに厄介なものになります。

ご協力いただきありがとうございます。

4

1 に答える 1