我有一个使用Django Rest Framework的API,我希望防止重复的POST
请求(本着Post Exactly Once (POE)的精神)。特别是,我试图处理的场景是:
对此on the mailing list进行了一些讨论,但没有实现代码。人们现在如何解决这个问题?
答案 0 :(得分:3)
我通过添加对X-Idempotency-Key
http标头的支持来解决这个问题,该标头可以由客户端设置。然后,我使用自定义权限类检查非幂等请求:
class IsIdempotent(permissions.BasePermission):
message = 'Duplicate request detected.'
def has_permission(self, request, view):
if request.method != 'POST':
return True
ival = request.META.get('HTTP_X_IDEMPOTENCY_KEY')
if ival is None:
return True
ival = ival[:128]
key = 'idemp-{}-{}'.format(request.user.pk, ival)
is_idempotent = bool(cache.add(key, 'yes',
settings.IDEMPOTENCY_TIMEOUT))
if not is_idempotent:
logger.info(u'Duplicate request (non-idempotent): %s', key)
return is_idempotent
我可以像这样添加到我的观点中:
class MyViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
permission_classes = [permissions.IsAuthenticated,
IsIdempotent]