7

django-rest-framework を使用して、Django REST API に Auth0 JWT ベースの認証を実装しようとしています。REST フレームワークで利用できる JWT ライブラリがあることは知っており、Auth0 の公式 Twitter アカウントが auth0 + Django でうまく動作すると述べていたので、それを使用してみました。

編集:このコードには、公式の auth0 python api ガイドを使用しています。これはフラスコ用に書かれていますが、Django と同様に動作することを確認して、Django に移植できると考えました。

さて、それは私が望んでいた方法ではうまくいかなかったのでlogin_required、ビュー用に独自のデコレータを作成しようとしています。ここにあるコードは次のとおりです。

def auth_required(f):

    def wrap(request, *args, **kwargs):
        auth = request.META.get('HTTP_AUTHORIZATION', None)

        if not auth:
            return authenticate({'code': 'authorization_header_missing', 'description': 'Authorization header is expected'})

        parts = auth.split()

        if parts[0].lower() != 'bearer':
            return authenticate({'code': 'invalid_header', 'description':     'Authorization header must start with Bearer'})
        elif len(parts) == 1:
            return authenticate({'code': 'invalid_header', 'description':     'Token not found'})
        elif len(parts) > 2:
            return authenticate({'code': 'invalid_header', 'description': 'Authorization header must be Bearer + \s + token'})

        token = parts[1]
        try:
            payload = jwt.decode(
                token,
                base64.b64decode(SECRET.replace("_","/").replace("-","+")),
                audience=CLIENT_ID,
            )
        except jwt.ExpiredSignature:
            return authenticate({'code': 'token_expired', 'description': 'token is expired'})
        except jwt.InvalidAudienceError:
            return authenticate({'code': 'invalid_audience', 'description': 'incorrect audience, expected: ' + CLIENT_ID})
        except jwt.DecodeError:
            return authenticate({'code': 'token_invalid_signature', 'description': 'token signature is invalid'})


        return f(request, *args, **kwargs)

    wrap.__doc__=f.__doc__
    wrap.__name__=f.__name__

    return wrap

さて、これauthenticate()は基本的に私のカスタム実装でJsonify()あり、Auth0 for Python API のドキュメントで使用されています。動作確認済みですので問題ありません。

SECRETbase64 でエンコードされた私の Auth0 シークレット (他のキーはデコードに失敗しました)
CLIENT_IDは、Auth0 ドキュメントによると、オーディエンスとして使用される私の Auth0 クライアント ID です。

フロントエンド側で Angular シード プロジェクトを使用しており、トークンが実際にリクエストと共に送信されることを確認しtoken、バックエンドの変数に格納されるのとまったく同じトークンであることを確認しました。

jwt.decode()呼び出されると、毎回がトリガーされます。jwt.DecodeErrorこれを修正するために数え切れないほどの時間を費やしてきましたが、なぜこれが機能しないのか完全に唖然としています。JWT オプションを false に設定してみました。具体的には、署名の検証オプションです。これは機能しましたが、JWT 署名の検証を無効にするのは安全ではないと思います。

なぜこれが私を失敗させているのか分かりません。デコレータに入れずにこの同じコードを試してみましたが、同じことをします。装飾されたビューは、OK HttpResponse を返す単なる空のビューです。

Tldr; Django-REST + Auth0 JWT を使用jwt.decode()すると、何をしても機能しません。

EDIT2corsheaders :クロスドメインリクエストを作成できるdjango-restを使用していることに言及する価値があります。また、Auth0 の Python API ガイドの下部にあるヒントに従って、JWT ライブラリをアンインストールして再インストールしましたが、これは何もしませんでした。

私は何かを見落としていますか、この実装は単純に安全ではありませんか、それとも Django で Auth0 を実装するためのより良い方法はありますか? 教えてください、この問題は私に悪夢を引き起こしています。

4

2 に答える 2

5

「修正するのが最も難しいバグは、通常、最も愚かなバグである」という典型的なケース...

Auth0 ダッシュボードから秘密鍵をダブルクリックしてコピーしましたが、コピーされていない部分があることに気づきませんでした。これで修正されました。

必要に応じて、独自のプロジェクトでカスタム デコレータを使用して、JWT を検証できます。

それをインポートして、次のように使用します。

@auth_required
def myView(request):
    ....
于 2015-12-22T23:59:22.243 に答える
1

Django API で auth0 を実行する際に同様の問題があったため、最近、いくつかの問題を修正するパッケージを作成しました: https://github.com/mcueto/djangorestframework-auth0

于 2016-03-25T02:46:32.690 に答える