Django+Auth0 JWT身份验证拒绝解码



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

EDIT:我使用官方的auth0-pythonAPI指南来编写这段代码。它是为flask编写的,但我想我可以把它移植到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的文档中使用。我已经验证了这是有效的,所以这不是问题。

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

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

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

我不明白为什么这会让我失败,我在没有装饰器的情况下尝试了同样的代码,它也做了同样的事情。被修饰的视图只是一个返回OK HttpResponse的空视图。

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

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

我是不是忽略了什么,这个实现是完全不安全的,还是你有更好的方法用Django实现Auth0?请告诉我,这个问题让我做噩梦。

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

我双击Auth0面板复制了密钥,但没有意识到有些部分没有被复制。这修复了它。

如果你愿意,你可以在你自己的项目中使用我的自定义装饰器来验证JWT。

你导入它,然后像这样使用它:

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

我在Django API上执行auth0时遇到了类似的问题,所以我最近创建了一个包来修复一些问题:https://github.com/mcueto/djangorestframework-auth0

最新更新