Django + Auth0 JWT 认证拒绝解码 [英] Django + Auth0 JWT authentication refusing to decode

查看:36
本文介绍了Django + Auth0 JWT 认证拒绝解码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 django-rest-framework 在我的 Django REST API 中实现基于 Auth0 JWT 的身份验证.我知道有一个可用于 REST 框架的 JWT 库,我尝试使用它,因为官方 Auth0 推特帐户提到它应该可以很好地与 auth0 + Django 配合使用.

I am trying to implement Auth0 JWT-based authentication in my Django REST API using the django-rest-framework. I know that there is a JWT library available for the REST framework, and I have tried using it because the official Auth0 twitter account mentioned that it should work well with auth0 + Django.

编辑:我正在使用官方 auth0 python api 指南来编写此代码.它是为 Flask 编写的,但我想我可以将它移植到 Django,因为它们的工作方式相似.

EDIT: I am using the official auth0 python api guide for this code. It's written for flask, but I figured I could just port it to Django seeing as they work similarly.

现在,这并没有达到我想要的效果,所以我正在尝试为视图编写自己的 login_required 装饰器.我这里的代码如下:

Now, that didn't work out how I wanted to, so I am trying to write my own login_required decorater for a view. The code I have here is as following:

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() 的自定义实现,它用于 Python API 的 Auth0 文档中.我已经验证这有效,所以这不是问题.

Now, the authenticate() is basically my custom implementation for Jsonify() which is used in the documentation of Auth0 for Python API's. I have verified that this works, so that's not a problem.

SECRET 是我的 Auth0 秘密,以 base64 编码(任何其他密钥都无法解码)
根据 Auth0 文档,CLIENT_ID 是我用作受众的 Auth0 客户端 ID.

SECRET is my Auth0 secret, encoded in base64 (any other keys failed to decode)
CLIENT_ID is my Auth0 client ID which is used as the audience, according to the Auth0 documentation.

我在前端使用 Angular 种子项目,并且我已经验证令牌确实是随请求一起发送的,并且我已经验证它与存储在 token<中的令牌完全相同/code> 后端变量.

I am using the Angular seed project on the frontend-side, and I have verified that the token indeed gets sent with the request, and I have verified that it's the exact same token that gets stored in the token variable on the backend.

jwt.decode() 被调用时,它每次都会触发 jwt.DecodeError,我已经花了无数个小时试图解决这个问题,但我我完全震惊于为什么这 工作.我尝试将 JWT 选项设置为 false,特别是验证签名选项.这有效,但我认为禁用 JWT 签名验证不安全.

When jwt.decode() is called, it will trigger the jwt.DecodeError every time, and I have been spending countless hours trying to fix this, but I am absolutely stunned as to why this is not working. I have tried setting the JWT options to false, specifically the verify signature one. This worked, but I assume that it's unsafe to disable the verifying of the JWT signature.

我不知道为什么这让我失败了,我已经尝试了相同的代码,而没有将它放在装饰器中,它做同样的事情.被装饰的视图只是一个返回 OK HttpResponse 的空视图.

I cannot figure out why this is failing me, I have tried this same code without it being in a decorator and it does the same thing. The view which is decorated is just an empty view which returns an OK HttpResponse.

Tldr;使用 Django-REST + Auth0 JWT -- jwt.decode() 无论我做什么都不起作用.

Tldr; Using Django-REST + Auth0 JWT -- jwt.decode() will not work no matter what I do.

EDIT2:值得一提的是,我是 django-rest 的 corsheaders,它允许我进行跨域请求.我还按照 Auth0 的 Python API 指南底部的提示卸载并重新安装了 JWT 库,但这对我没有任何帮助.

EDIT2: It's worth mentioning I am corsheaders for django-rest which allows me to make cross-domain requests. I have also followed the tip at the bottom of the Python API guide from Auth0 to uninstall and reinstall the JWT library, but this did nothing for me.

我是否忽略了一些东西,这个实现是不安全的还是你有更好的方法来用 Django 实现 Auth0?请让我知道,这个问题让我做噩梦.

Am I overlooking something, is this implementation plain unsecure or do you have any better way to implement Auth0 with Django? Please let me know, this problem is causing me nightmares.

推荐答案

最难修复的错误通常是最愚蠢的错误"的经典案例...

我通过双击从 Auth0 仪表板复制了密钥,没有意识到有些部分没有被复制.这修复了它.

I copied the secret key from the Auth0 dashboard by doubleclicking it, not realizing there were parts which didn't get copied. This fixed it.

如果需要,您可以在自己的项目中使用我的自定义装饰器来验证 JWT.

If you want, you can use my custom decorator in your own project, to verify the JWT's.

您导入它然后像这样使用它:

You import it and then use it like so:

@auth_required
def myView(request):
    ....

这篇关于Django + Auth0 JWT 认证拒绝解码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆