如何使 Django REST JWT 身份验证与多个 Web 服务器一起扩展?

Posted

技术标签:

【中文标题】如何使 Django REST JWT 身份验证与多个 Web 服务器一起扩展?【英文标题】:How to make Django REST JWT Authentication scale with mulitple webservers? 【发布时间】:2014-11-25 10:09:40 【问题描述】:

我目前有一个 Django 应用程序,它只是一堆 REST API(当然由数据库支持)。我正在使用Django REST framework JWT 管理我的身份验证。它工作正常。每当用户登录时,我的一个 API 都会返回一个令牌,消费应用程序存储该令牌以供以后使用。到目前为止一切顺利。

但是,在未来,此解决方案将需要扩展。而不是让单个服务器运行 Django 应用程序,我可以预见需要多个 Web 服务器的情况。当然,所有这些网络服务器都将连接到同一个数据库。但是由于令牌没有存储在数据库中,这将如何与多个 Web 服务器一起工作?一个服务器发出的令牌在另一台服务器上无效。

那么其他人是如何解决这个问题的??

【问题讨论】:

【参考方案1】:

简而言之,您确实需要担心使用 JWT 进行扩展

详细说明:

首先我们了解下Django-Rest-Framework(DRF)提供的默认token认证和DRF-JWT提供的token的实现区别

DRF 提供的令牌

rest_framework.authentication.TokenAuthentication

令牌创建:

1) 创建令牌

Token.objects.create(user=user)

2) 将步骤1创建的令牌存储在数据库中

3) 将令牌返回给客户端

令牌认证:

1)检查客户端传递的token是否存在于数据库中

2)如果令牌存在,则表示用户已通过身份验证

DRF-JWT 提供的令牌

rest_framework_jwt.authentication.JSONWebTokenAuthentication

令牌创建:

1) 创建令牌

body = base64encode(header) + "." + base64encode(有效负载)

signature = HMACSHA256_encode(body, 'secret_key') #secret key 通常在你的 settings.py 中指定

token = body + "." + 签名

2) 将令牌返回给客户端

令牌认证:

1)解码令牌

token_segment = token.split('.')

body = token_segment[0] + "." + token_segment[1]

签名 = token_segment[2]

decode_body = HMACSHA256_decode(signature, 'secret_key')

2)如果decode_body等于body,则用户通过身份验证

结论

从上面的机制,我们可以有把握地得出结论,JWT 方法更具可扩展性,因为它只依赖于 secret_key,并且每个 web 服务器都应该在 settings.py 下拥有 secret_key

所以要回答你的问题,你不必担心缩放它:)

【讨论】:

【参考方案2】:

取决于您认为数据库会被击中的频率。我的第一直觉是缓存令牌并为此使用 memcached。 Django 对此有很好的支持。如果您使用的是 GAE/Python 或 AWS 等云平台,情况会有所不同(配置方面),但两者都有解决方案,而且难度不大。

【讨论】:

如果我将令牌缓存在 memcached 中,这将如何工作?是否会有一个 memcached 将由所有实例共享?这是在 AWS EC2 上。 单个逻辑内存缓存。请记住,memcached 是一种分布式服务,是来自多个实例的单个虚拟内存池。查一下。

以上是关于如何使 Django REST JWT 身份验证与多个 Web 服务器一起扩展?的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest Framework 不接受 JWT 身份验证令牌

Django 通道 JWT 身份验证

Django Rest Framework(DRF) Json Web Token(JWT) 身份验证和登录过程

Django Rest Framework 中的 JWT 身份验证错误“无效签名”

Django Rest Framework JWT 身份验证测试

使用 Django REST 框架进行 JWT 身份验证