我需要使用基于SMS的OTP对django rest框架应用程序中的用户进行身份验证。为此,我创建了以下API端点
GET \otp - generate and send OTP and store it in cache
POST \otp - validate OTP based on value store in cache
这是我的密码-
from django.core.cache import cache
# It is used just for debugging & logging purpose
local_cache = {}
class OTPView(APIView):
def get(self, request):
serializer = ContactSerializer(data=request.query_params)
num = serializer.validated_data.get('contact_number')
otp = generate_otp()
cache.set(num, otp, 300)
local_cache[num] = otp
print('GET Cache is : ', local_cache)
return Response('OTP Sent')
def post(self, request):
serializer = OTPSerializer(data=request.data)
num = serializer.validated_data.get('contact_number')
otp = serializer.validated_data.get('otp')
print('POST Cache is : ', local_cache)
otp_in_cache = cache.get(num)
if otp_in_cache is None:
return Response('No OTP or prev expired')
elif otp == otp_in_cache:
return Response('Success')
else:
return Response('Incorrect OTP')
要在内存缓存中使用的两个请求之间持久化OTP。它在我的本地机器上按预期工作,但在部署到Heroku上时却无法正常工作。以下是heroku的日志供参考-
2020-09-02T17:17:22.556785+00:00 app[web.1]: Number is 6666660008 and otp is 541609
2020-09-02T17:17:22.556798+00:00 app[web.1]: GET Cache is : {'6666660008': '541609'}
2020-09-02T17:17:22.558975+00:00 app[web.1]: 10.69.31.173 - - [02/Sep/2020:22:47:22 +0530] "GET /account/api/otp/?contact_number=6666660008 HTTP/1.1" 200 36 "https://direct-fresh-chicken.netlify.app/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/77.0.3865.90 Chrome/77.0.3865.90 Safari/537.36"
2020-09-02T17:17:32.897997+00:00 app[web.1]: POST Cache is : {}
2020-09-02T17:17:32.898035+00:00 app[web.1]: Error 400: No OTP or prev expired.
2020-09-02T17:17:32.900342+00:00 app[web.1]: 10.69.31.173 - - [02/Sep/2020:22:47:32 +0530] "POST /account/api/otp/ HTTP/1.1" 400 66 "https://direct-fresh-chicken.netlify.app/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/77.0.3865.90 Chrome/77.0.3865.90 Safari/537.36"
我知道本地内存缓存不适合生产,最终我计划使用更好的替代方案,如memcached
我想知道-
local_cache
字典对象在post方法中有空值(请参阅日志)李>
关于Heroku上的本地内存缓存
一般来说,本地内存缓存在Heroku上运行良好。但是有一个限制:dict和Django
locmem
缓存后端都是进程和dyno的本地因此,例如,如果您使用} setting is at least 2, depending on the dyno size
gunicorn
,默认情况下它将使用子进程来处理请求。每个子进程都有自己的locmem
缓存。这个default ^{现在关于一般设置问题:
一般来说,本地缓存对于生产使用来说是完全好的(而且速度非常快),前提是进程/动态限制对您来说很好,并且您无法在不重新启动所有动态对象的情况下清除整个缓存
文件系统缓存也可以工作,但也只是dyno的本地缓存,这意味着只有通过重新启动所有dyno才能进行清理
在一个应用程序有多个服务器/容器的环境中,实际上最好有一个单独的缓存,比如redis、memcached等等。。。所有的迪诺人都能进入
缓存和OTP
通常,您可以使用此处的缓存来存储令牌。这里的风险在于,具体取决于实际的缓存后端:如果缓存已满,它将删除数据。对于真正的缓存来说,这通常是很好的,但对于OTP来说,这将是一个问题
在您的例子中,您可以configure separate cache only for the OTP tokens,它足够大,可以容纳所有当前有效的令牌
相关问题 更多 >
编程相关推荐