根据标头身份验证令牌过滤API请求

时间:2016-11-08 04:05:13

标签: python django django-rest-framework

我想根据使用GET请求发送的令牌标头来过滤对象。

我的请求是在标头(get curl -H "Authorization: Token 3f3f3fzzz" https://1.com/api

中发送令牌

下面的代码没有返回任何结果(只是一个空数组 - 没有错误)。我无法确定请求对象标头的位置。

我的猜测是我需要一些中间件函数来改变响应并将用户对象放入其中。

views.py

class AllViewSet(viewsets.ModelViewSet):
    queryset = Movie.objects.order_by('-created',)
    serializer_class = AllSerializer
    def get_queryset(self):
        Movie.objects.filter(owner = self.request.user)

我在def_queryset之后尝试了一些调试(使用import pdb; pdb.set_trace())。

def(sel.request)返回:http://dpaste.com/2VQARE3

以下是我的代码中可能相关的其他部分。

models.py

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

class Movie(models.Model):
    title = models.CharField("Title", max_length=10000, blank=True)
    tag = models.ManyToManyField('Tag', blank=True)
    created = models.DateTimeField("Created", auto_now_add=True)
    owner = models.ForeignKey('auth.User', blank=True, null=True)

setting.py

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    )
}

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

2 个答案:

答案 0 :(得分:1)

如果您希望此视图始终返回所有者电影的查询集,则可以通过请求对象self.request.META访问标题(标题应该可用,请查看内容类型在文档中)然后解码令牌以找到连接到它的关联用户。

所以在你的查询集中

def get_queryset(self):
   access_token = self.request.META.get('TOKEN')
   user_from_token = find_user_given_token(access_token)
   return Movie.objects.filter(owner = user_from_token)

或者,如果meta因某些奇怪的原因或配置不可用,您可以通过查询参数传递令牌。 'https://1.com/api?token= 3f3f3fzzz'

然后在您看来,您可以通过self.request.query_params['token']

访问它

此外,您需要提供获取令牌的方式,以便解释如何解码令牌。

答案 1 :(得分:1)

您可以编写自定义过滤器后端http://www.django-rest-framework.org/api-guide/filtering/#custom-generic-filtering

from rest_framework import filters
class OwnerFilterBackend(filters.BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        return queryset.filter(owner=request.user)

class AllViewSet(viewsets.ModelViewSet):
    filter_backends = (OwnerFilterBackend,)
    ...