我正在尝试使用django-rest-framework在我的Django REST API中实现基于Auth0 JWT的身份验证.我知道有一个可用于REST框架的JWT库,我尝试使用它,因为官方的Auth0 twitter帐户提到它应该与auth0 + Django一起使用.
编辑:我正在使用官方auth0 python api指南为此代码.它是为烧瓶而写的,但我想我可以将它移植到Django,因为它们的工作方式类似.
现在,这并没有解决我想要的问题,因此我正在尝试login_required
为视图编写自己的decorater.我在这里的代码如下:
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
CLIENT_ID
根据Auth0文档,我的Auth0秘密,以base64编码(任何其他密钥无法解码)是我的Auth0客户端ID,用作受众.
我正在前端使用Angular种子项目,并且我已经验证了令牌确实随请求一起发送,并且我已经验证它是存储在token
后端变量中的完全相同的令牌.
当jwt.decode()
被调用时,它会触发jwt.DecodeError
每一次,我已经花了无数的时间试图解决这一问题,但我为什么这是绝对惊呆了未工作.我已经尝试将JWT选项设置为false,特别是验证签名选项.这有效,但我认为禁用JWT签名的验证是不安全的.
我无法弄清楚为什么这会让我失望,我已经尝试过这个相同的代码而不是它在装饰器中并且它做同样的事情.装饰的视图只是一个返回OK HttpResponse的空视图.
Tldr; 使用Django-REST + Auth0 JWT - jwt.decode()
无论我做什么都不会工作.
EDIT2:值得一提的是我是corsheaders
django-rest,它允许我发出跨域请求.我还按照Auth0的Python API指南底部的提示卸载并重新安装了JWT库,但这对我没有任何帮助.
我忽略了什么,这个实现是不安全的,还是你有更好的方法用Django实现Auth0?请让我知道,这个问题让我做恶梦.
一个典型的"最难解决的错误通常是最愚蠢的" ......
我通过双击它从Auth0仪表板复制了密钥,没有意识到有些部分没有被复制.这解决了它.
如果需要,可以在自己的项目中使用我的自定义装饰器来验证JWT.
您导入它,然后像这样使用它:
@auth_required def myView(request): ....