Django + Auth0 JWT 身份验证拒绝解码
Posted
技术标签:
【中文标题】Django + Auth0 JWT 身份验证拒绝解码【英文标题】:Django + Auth0 JWT authentication refusing to decode 【发布时间】:2016-03-29 07:42:24 【问题描述】:我正在尝试使用 django-rest-framework 在我的 Django REST API 中实现基于 Auth0 JWT 的身份验证。我知道有一个可用于 REST 框架的 JWT 库,并且我已经尝试使用它,因为官方 Auth0 twitter 帐户提到它应该可以很好地与 auth0 + Django 一起使用。
编辑:我在这段代码中使用the official auth0 python api guide。它是为烧瓶编写的,但我想我可以将它移植到 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()
的自定义实现,它在 Python API 的 Auth0 文档中使用。我已验证此方法有效,所以这不是问题。
SECRET
是我的 Auth0 密码,以 base64 编码(任何其他密钥都无法解码)CLIENT_ID
是我的 Auth0 客户端 ID,根据 Auth0 文档,它用作受众。
我在前端使用 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 与 django rest 框架一起使用。你有任何我可以看到的源代码吗?如果可以的话,真的会有很大帮助! @nextdoordoc 非常抱歉,但我的实现太糟糕了,我中途放弃了。您最好尝试找到为另一种语言编写的实现并将其移植。 哦,很遗憾听到这个消息。顺便说一句,你终于用其他语言来使用 auth0 了?还是你最终使用了另一个身份验证工具? 我尝试将 Auth0 用于辅助项目。在我无法让它与 Django 一起工作后,我使用了 Auth0 node.js 库,它是这里的开源库:github.com/auth0/node-auth0 【参考方案1】:我在我的 Django API 上执行 auth0 时遇到了类似的问题,所以我最近创建了一个包来解决一些问题:https://github.com/mcueto/djangorestframework-auth0
【讨论】:
【参考方案2】:“最难修复的错误通常是最愚蠢的错误”的经典案例...
我通过双击从 Auth0 仪表板复制了密钥,没有意识到有些部分没有被复制。这解决了它。
如果你愿意,你可以在你自己的项目中使用我的自定义装饰器,来验证 JWT 的。
你导入它,然后像这样使用它:
@auth_required
def myView(request):
....
【讨论】:
对不起!这是有用的反馈,我们将在 Auth0 仪表板中改进此用户体验。以上是关于Django + Auth0 JWT 身份验证拒绝解码的主要内容,如果未能解决你的问题,请参考以下文章
Auth0 NodeJS JWT 身份验证在移动应用程序的 API 中
AWS API Gateway 身份验证错误 IncompleteSignatureException 使用带有 Auth0 的 JWT
Auth0 - 在 Owin 上使用带有承载访问令牌的 JWT 使用 RS256 进行身份验证
使用 Auth0Lock 与 express + angular2 应用程序进行身份验证,“UnauthorizedError: jwt malformed”