Django jwt 通道无法验证

Posted

技术标签:

【中文标题】Django jwt 通道无法验证【英文标题】:Django jwt channels cannot verify 【发布时间】:2022-01-21 18:57:35 【问题描述】:

我使用 djangorestframework-simplejwt。

我有两个 Django 项目共享同一个数据库。

一个是django-restframework

一个是django-channels

django-restframework 登录会得到JWT

我无法在 django-channels 中成功验证

我写了测试函数

restframework 验证正常

class Test(APIView):
    def get(self, request):
        try:
            token = UntypedToken(
                'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.???.Z22plhyGEZW9IBZLzICu2mWTkuMrblYQhvUGoUtpKd0')
            print(token, 'token')   # output: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.???.Z22plhyGEZW9IBZLzICu2mWTkuMrblYQhvUGoUtpKd0
        except (InvalidToken, TokenError):
            print('InvalidToken, TokenError')
        return Response(status=status.HTTP_200_OK)

渠道验证错误

@database_sync_to_async
def test_get_user():
    try:
        token = UntypedToken(
            'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.???.Z22plhyGEZW9IBZLzICu2mWTkuMrblYQhvUGoUtpKd0')
        print(token, 'token')
    except (InvalidToken, TokenError) as e:
        print('InvalidToken, TokenError', e)  # output InvalidToken, TokenError Token is invalid or expired

无法像这样验证 JWT?

追溯

Exception inside application: Token is invalid or expired
Traceback (most recent call last):
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/rest_framework_simplejwt/backends.py", line 99, in decode
    'verify_signature': verify,
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/jwt/api_jwt.py", line 119, in decode
    decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/jwt/api_jwt.py", line 95, in decode_complete
    **kwargs,
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/jwt/api_jws.py", line 152, in decode_complete
    self._verify_signature(signing_input, header, signature, key, algorithms)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/jwt/api_jws.py", line 239, in _verify_signature
    raise InvalidSignatureError("Signature verification failed")
jwt.exceptions.InvalidSignatureError: Signature verification failed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/rest_framework_simplejwt/tokens.py", line 43, in __init__
    self.payload = token_backend.decode(token, verify=verify)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/rest_framework_simplejwt/backends.py", line 105, in decode
    raise TokenBackendError(_('Token is invalid or expired'))
rest_framework_simplejwt.exceptions.TokenBackendError: Token is invalid or expired

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/staticfiles.py", line 44, in __call__
    return await self.application(scope, receive, send)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/routing.py", line 71, in __call__
    return await application(scope, receive, send)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/sessions.py", line 47, in __call__
    return await self.inner(dict(scope, cookies=cookies), receive, send)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/sessions.py", line 263, in __call__
    return await self.inner(wrapper.scope, receive, wrapper.send)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/auth.py", line 185, in __call__
    return await super().__call__(scope, receive, send)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/middleware.py", line 26, in __call__
    return await self.inner(scope, receive, send)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/routing.py", line 160, in __call__
    send,
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/consumer.py", line 94, in app
    return await consumer(scope, receive, send)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/consumer.py", line 59, in __call__
    [receive, self.channel_receive], self.dispatch
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/utils.py", line 51, in await_many_dispatch
    await dispatch(result)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/consumer.py", line 73, in dispatch
    await handler(message)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/generic/websocket.py", line 173, in websocket_connect
    await self.connect()
  File "/home/user/Daniel/Python/GitLab/django-signalserver/WebSocket/consumers.py", line 147, in connect
    await test_get_user()
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/asgiref/sync.py", line 444, in __call__
    ret = await asyncio.wait_for(future, timeout=None)
  File "/usr/lib/python3.7/asyncio/tasks.py", line 414, in wait_for
    return await fut
  File "/usr/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/channels/db.py", line 13, in thread_handler
    return super().thread_handler(loop, *args, **kwargs)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/asgiref/sync.py", line 486, in thread_handler
    return func(*args, **kwargs)
  File "/home/user/Daniel/Python/GitLab/django-signalserver/WebSocket/consumers.py", line 127, in test_get_user
    'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.???.Z22plhyGEZW9IBZLzICu2mWTkuMrblYQhvUGoUtpKd0')
  File "/home/user/Daniel/Python/GitLab/django-signalserver/venv/lib/python3.7/site-packages/rest_framework_simplejwt/tokens.py", line 45, in __init__
    raise TokenError(_('Token is invalid or expired'))
rest_framework_simplejwt.exceptions.TokenError: Token is invalid or expired

【问题讨论】:

能否添加错误回溯? 渠道验证错误:InvalidToken, TokenError Token is invalid or expired 我的意思是traceback,而不是错误消息。 这个? rest_framework_simplejwt.exceptions.TokenError: Token is invalid or expired。我更新了。 【参考方案1】:

因为我不知道 jwt 是如何验证的

现在发现settings.py中的验证方式是SECRET_KEY

只要不同的项目使用相同的SECRET_KEY

JWT 认证没有问题。

【讨论】:

以上是关于Django jwt 通道无法验证的主要内容,如果未能解决你的问题,请参考以下文章

用于通道 websocket 身份验证的 Django jwt 中间件

Django Rest Framework JWT 身份验证测试

在测试期间使用 Django Rest + JWT 进行身份验证

在 Django 中使用 JWT 进行身份验证

基于类的视图django中的JWT验证

如何在 django rest 框架中验证 jwt 身份验证中的令牌